SPS Commerce内部开发者门户搭建揭秘

10 阅读13分钟

SPS Commerce 通过构建内部开发者门户,解决了工具蔓延和缺乏应用上下文的问题。他们选择 Port,因为它提供了数据模型的灵活性和内置的界面设计器。门户通过整合数据源、提供自助服务操作和构建可扩展的数据模型,提高了开发效率和协作,并实现了对平台迁移、Kubernetes升级和API目录的实时可见性。

译自:How SPS Commerce Built Its Internal Developer Portal

作者:Travis Gosselin, Mark DeBeer

实施内部开发者门户不仅仅是选择一个工具;更是通过致力于平台工程的最佳实践,重塑您的工程团队的工作方式并真正地赋能他们。如果您正在考虑为您的组织采取这条道路,请从我们在 SPS Commerce 的经验中学习。我们运营着世界上最大的零售网络,连接着供应商和零售商。我们促进全球供应链中采购订单和发票等文件的交换。超过 50,000 名客户使用我们的网络,我们的技术部门拥有 700 名员工。

糟糕的开发者体验

近年来,随着组织机构的快速发展,我们的 服务目录 中迅速积累了超过 2,500 个活跃项目。随着新开发者的加入和一套新工具的管理,我们的开发者生产力工程团队有了一项新的任务,即设计更好的工作方式。

我们很快意识到我们需要更好地支持和赋能我们的工程师:我们的团队规模更大,分布在各个项目中,缩小流程之间的差距给我们的开发者带来了压力。

一个重要的问题是 工具蔓延。由于有超过 20 种开发工具正在积极使用,并且计划开发或采用更多工具,我们看到我们的开发者 每周花费无数时间 来应对一个脱节的生态系统。

更糟糕的是,没有一个中心枢纽可以查看应用程序的完整上下文。想象一下,如果无法在一个地方显示 2,500 项服务,你该如何理解它们!这种缺乏清晰度的情况,在我们的快速发展中被放大,导致我们创建了不同的流程,并在不同的技术堆栈中存在零星的文档,这使得工作孤立,并隔离了本应共享的知识。

寻找解决方案

我们寻找解决方案的第一步是创建一个 内部开发者平台,这帮助我们抽象化了团队面临的一些复杂性。但我们很快就遇到了平台的局限性。团队仍然需要近两周的时间才能实现他们的第一个“Hello, world!”。

尽管入职过程很痛苦,但该平台教会了我们一些关于上下文以及如何呈现它的重要经验。即使我们的软件开发流水线的细节被清楚地列出,也存在如此多的细节,以至于很难区分相关和不相关的数据点。

上下文需要显而易见:如果开发者仍然需要从多个来源拼凑信息,那么该平台的好处就会丧失。因此,我们问自己,什么上下文是必不可少的?我们的平台如何在提供必要上下文的同时,为开发者提供输入他们自己见解的方式?

选择内部开发者门户

我们做了调查,并确定 内部开发者门户 可能是提供我们需要的双向上下文的解决方案。但是市场提供了几种不同的选择,每种选择都有其权衡。

我们认真研究了从平台计划中学到的东西以及我们仍然需要的东西,然后提出了一些关键问题:

  • 我们准备好迎接开发者门户了吗? 我们是否已经采取了一些步骤来集中一些上下文——也许使用某种类型的标记或分类系统?(幸运的是,我们在平台计划期间已经开始对进行分类。)
  • 谁将加入我们的实施团队? 他们是专注于前端还是后端?他们喜欢什么语言?有多少专门的开发者可以参与这个项目,以及持续多长时间?
  • 我们的工具链有多自定义? 它是如此自定义以至于不适合刚性的数据模型,还是我们正在使用 AWS 和 Azure 流水线等标准工具,这些工具大多数门户都开箱即用支持?(事实证明我们的工具链是标准的。)

根据我们的研究,我们发现一些门户提供了更刚性的数据模型,这吸引了我们的执行团队,因为设置会很快。但是这些门户无法适应我们所有的需求,因为它们的刚性——这有可能阻碍我们的长期采用,甚至可能阻碍我们为团队开发可用解决方案的能力。

另一方面,我们看到了“非主观”的开发者门户,它们是完全可定制的,但需要比我们能花费的更多的初始投资才能设置,以及增加长期的维护、成本和风险。

我们知道,如果我们想提高开发者体验的质量,我们需要找到一个可以为我们提供一些意见的门户,比如最佳实践,同时在我们的需求发生变化时保持长期的灵活性。

我们对市场上的一切进行了彻底的评估,从开源门户选项一直到刚性门户。最终,我们选择 Port 的原因如下:

  • 数据模型和数据摄取的灵活性
  • 内置的界面设计器,它提供了一个直观的 UI,使上传和建模数据变得轻而易举
  • 可以选择继续使用基础设施即代码来设计门户,这使我们能够在多个环境中采用例行的发布计划

门户可以为我们做什么

我们最兴奋的事情之一是弄清楚如何构建我们的团队,并为我们的开发者门户开发所有权模型。

我们拥抱同理心驱动的开发——与 了解交付团队日常需求的工程师一起构建门户。我们将报告路线调整为矩阵结构,团队向不同的 VP 级别的垂直部门报告,但定期协作。

这种方法提供了巨大的好处。按照 团队拓扑 框架,我们的交付团队现在充当与流对齐的团队,由 SRE、平台和云等平台团队支持。我们的开发者生产力工程团队则充当支持团队,将同理心和洞察力融入交付需求中。

我们还明确了团队的方法和目标:不是消除工具蔓延,而是通过连接工具和上下文来管理它。我们没有复制每个 UI,例如 Kubernetes 仪表板,而是专注于深度链接到它们,并将正确的上下文构建到 URL 中。

我们早期取得的另一个重大胜利是通过基础设施即代码 (IaC) 改进了我们的构建器体验。这帮助我们的开发者生产力团队快速原型化数据模型、映射和操作,使我们能够快速迭代并实时收集反馈。

一旦我们对配置感到满意,我们就使用 IaC 对其进行编码。这种方法在速度和可用性与跨体验的控制和一致性之间取得了平衡。

我们如何使我们的门户必不可少

回顾过去,在构建我们的开发者门户时,我们做出的最有价值的决定之一是首先优先将我们拥有的数据源集成到门户中。这很重要,不仅因为它们是我们软件交付生命周期 (SDLC) 的基础,而且因为我们的运营团队已经投入了大量时间来定义资源之间的所有权和关系。

我们能够从我们已经构建的内容中借用上下文,并围绕它构建门户的主要用例,使用我们已经实施的共享所有权和安全模型。这种熟悉感和跨方法的一致性帮助许多人以一致性和准确性来接受门户,而这种一致性和准确性通常会被排除在组织的软件目录之外。

鼓励采用

我们还需要考虑如何确保我们的开发团队采用该门户。我们认为构建一套高质量的自助服务操作是建立在我们基础数据源之上的好方法。

我们还希望简化跨团队的协作,同时让开发者快速、轻松地访问设置操作。该门户是我们可重用操作创建框架的技术基础,并为每个操作提供业务逻辑。

为了构建我们的自助服务操作,我们使用了:

  • Azure Pipelines 用于 CI/CD、部署和运行操作。
  • Docker 用于将操作逻辑打包到可移植的、与主机无关的容器中。
  • Pulumi 用于基础设施即代码,带有 Port 和 Azure Pipelines 的插件。
  • TypeScript 和 Python 用于编写业务逻辑,具体取决于团队的偏好。这是我们所有操作所需的通用功能,包括获取数据并将其发送到 Port 以及错误处理和日志记录。
  • Cookiecutter 用于生成操作脚手架并自动创建拉取请求。

为了将所有内容联系起来,我们创建了一套文档,包括“操作指南”和视频以及“入门”页面,以及一个 Slack 支持渠道来帮助那些开发门户的人。

现在,在门户中构建、部署和运行操作只需要大约五个文件。前四个文件配置操作以进行部署和运行时;最后一个文件包含逻辑。然后,我们更进一步:我们在开发者门户中创建的第一个操作是一个可以搭建操作的操作。这有助于我们鼓励其他团队做出贡献,而不会将所有负担都放在我们小型开发者生产力工程团队身上。

构建可扩展的数据模型

我们还对数据建模进行了很多思考。从一开始,我们就想要可扩展和可维护的模型。GitHub 是我们的第一个数据源,并且由于我们以类似的方式处理 Dependabot 和代码扫描警报,因此我们创建了一个统一的漏洞模型。这使得在一个地方查看和过滤所有漏洞变得更容易,并减少了重复。某些属性(如严重性)并没有完美地映射——例如,Dependabot 警报缺少“严重性”字段——但我们在需要时使用过滤器处理了这种情况。

对于存储库,我们构建了一个通用的代码存储库模型,其中包含一个“类型”字段来支持 GitHub 以外的平台,因为我们知道有一天我们可能会收购使用 GitLab 等工具的公司。这使我们能够通过简单地添加集成和映射来集成新源,而无需定义新模型。

虽然这种方法与我们统一相关数据的目标一致,但它在流水线等领域提出了问题,在这些领域,GitHub Actions 非常适合我们的流水线模型,但与流水线项目的概念相冲突。我们仍在寻找最佳解决方案。

使用通用模型需要更多的前期思考,但它帮助我们坚持开发者门户的目的:将信息整合在一起,而不是将它们分开。

一个更具连接性的 SDLC

我们的内部开发者门户由 Port 提供支持,为我们带来了几个切实的成果:

  • 我们终于可以实时了解平台迁移的进展。 我们最大的成功之一是让团队可以实时了解重大举措,例如我们的 CI/CD 代理迁移。以前,我们会分发包含要更新的服务静态列表的 Jira 工单,并且团队没有简单的方法来跟踪进度。现在,每个团队都可以直接在开发者门户中看到他们仍然需要迁移哪些服务。我们仍然有 Jira 工单,但它们只是链接到门户仪表板。在平台工程层面,我们也有自己的仪表板来监控整体进度。
  • 它使 Kubernetes 和 Helm chart 升级更易于管理。 我们对 Helm chart 升级使用了相同的方法。我们需要团队保持最新状态,以便我们可以快速使用 Kubernetes 版本,并且该门户使我们可以显示哪些服务仍然与阻止升级的旧 chart 相关联。这使团队可以更轻松地进行自助服务并保持最新状态。
  • 我们已经能够整合我们的 API 目录并增加 可观测性 Port 为我们提供了足够的灵活性,使我们可以开始整合我们的 API 设计优先工具。我们正在引入 OpenAPI 和 AsyncAPI 规范,将它们与服务目录对齐,并在上面添加合规性和治理数据。现在我们有了一个集中的 API 目录,它还可以显示 linting 状态、错误和警告等信息,所有信息都集中在一个地方。
  • 我们向更多人开放了功能标志数据。 以前,只有少数人可以访问功能决策提供者数据。现在,我们将该数据导入到门户中,以便任何需要 可观测性 的人(如经理、运营或随叫随到的人)都可以看到它。他们不再需要额外的许可证或特殊访问权限。我们已经能够创建视图来显示哪些标志是活跃的、不活跃的或随着时间的推移而过时的,这确实帮助团队清理了一些东西。
  • AI 代理了解 SDLC 数据。 使用门户来支持 AI 代理为我们提供了一个统一且结构化的数据模型,以便为他们提供他们也需要的上下文,并通过自助服务操作集成授予对代理的访问权限。现在,团队可以在 Slack 中提出直接问题,例如“服务 abc 上次何时投入生产?”

构建开发者门户并不是你真正“完成”的事情。这是一个持续的迭代、倾听和适应的过程。但到目前为止,它已经对我们团队的工作方式产生了有意义的影响,我们很高兴继续寻找方法来使 SPS 的开发者体验更好、更具连接性且更易于导航。