
Backstage 架构全景解析从三大组件、插件模型到包结构与缓存配置【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstageBackstage 是一个用于构建开发者门户Developer Portal的开源框架本指南基于仓库内 docs/overview/architecture-overview.md 展开系统梳理其整体架构三大核心组成部分Core、App、Plugins、前端与后端构建块、数据库与缓存方案、插件的三种架构形态以及 NPM 包架构。读完本文你将掌握 Backstage 各层组件间的依赖与通信关系能够据此规划自己的 Backstage 应用部署形态、理解如何编写和放置插件代码并能为生产环境正确配置数据库与缓存。术语与三大组成部分Backstage 被组织为三个主要组成部分分别面向不同的贡献者群体组成说明面向群体Core核心开源项目中由核心开发者构建的基础功能核心开发者App应用一个已部署的 Backstage 应用实例由应用开发者通常是组织内的生产力团队定制与维护集成核心功能并叠加额外插件应用开发者Plugins插件为增强 Backstage 应用而提供的附加功能可以是公司内部专用的也可以是开源的、可复用的插件开发者这套术语贯穿整个 Backstage 文档体系例如本仓库中的packages/目录承载了 Core 层的核心包packages/core-components、packages/frontend-plugin-api、packages/backend-defaults等plugins/目录则容纳了软件目录、Scaffolder、TechDocs 等众多官方插件。整体架构总览前端、后端与数据库在实际环境中运行 Backstage 架构通常需要将组件容器化仓库提供了多种命令辅助完成这一过程。架构中包含 3 个主要组件前端Frontend包含核心 Backstage 用户界面UIUI 本身是一个扩展直接与用户交互呈现来自核心功能插件以及用户添加的其他插件的信息。后端Backend包含后端插件、核心服务以及其他服务是 Backstage 的服务端部分负责把各个部件接线在一起。你可以按扩展和隔离单个功能的需要部署多个后端、多个后端容器。数据库Databases承载你的 Backstage 数据。这套架构与仓库中的packages/backend-defaults/src/CreateBackend.tscreateBackend的入口以及packages/frontend-app-api、packages/frontend-defaults等包一一对应后端由backend包组装启动前端由app包组装渲染两者通过 HTTP 与数据库交互。前端构建块Frontend Building Blocks前端架构图展示了各个构建块以及它们之间相互交互的其他构建块。AppApp 就是你自己创建的应用实例它是 Backstage 前端应用的根。App 本身不具备任何直接功能只负责把各个部件接线在一起——将内置扩展、插件扩展与覆盖扩展组装成一棵应用扩展树app extension tree整个应用据此实例化并渲染。扩展Extensions扩展是构建应用视觉与非视觉结构的构建块。既存在 App 自身提供的内置扩展也存在插件提供的扩展。每个扩展都挂载到一个父级上并与之共享数据也可以拥有任意数量的子扩展。扩展 ID 遵循[kind:][namespace][/][name]的构造模式输出数据通过扩展数据引用Extension Data Reference传递输入则由父扩展按需声明。用户界面User InterfaceUI 是前端中的一种扩展是围绕一组插件的轻量级客户端包装器提供一些核心 UI 组件和用于配置管理等共享活动的库。下图高亮了 UI 中哪些部分由核心core提供、哪些来自插件plugin每个插件通常都会在一个专属 URL 上向 UI 注册自己例如服务目录Service Catalog插件注册在/catalog路径。前端插件Frontend Plugins插件提供应用中的实际功能体量可以从一个微型组件到一整个可供其他插件组合集成的新系统。插件既可以完全独立也可以相互叠加以扩展现有插件插件之间通过组合各自的扩展、共享 Utility API 与路由来通信。Backstage 自带一组核心插件Software Catalog软件目录集中式系统保存所有软件服务、网站、库、ML 模型、数据管道等的元数据也可包含运行软件所需的物理或虚拟基础设施元数据可通过 UI 查看与搜索。Software Templates软件模板帮助在 Backstage 内创建组件的工具可加载代码骨架、包含变量并把模板发布到 GitHub 等位置。TechDocs内置的 docs-like-code 解决方案文档以 Markdown 编写并与代码一同存放。Kubernetes允许开发者检查其服务健康状况的工具无论服务位于本地主机还是生产环境。Search在 Backstage 生态中搜索信息可定制每个搜索结果的观感也可接入自己的搜索引擎。在仓库中这些插件的实现位于plugins/catalog、plugins/scaffolder、plugins/techdocs、plugins/kubernetes、plugins/search等目录前后端各成体系。扩展覆盖Extension Overrides除了内置扩展和插件提供的扩展还可以安装扩展覆盖一组具有高优先级的扩展能够替换现有扩展。例如可以用来覆盖插件提供的某个扩展或安装一个全新的扩展如新的应用主题。Utility APIsUtility APIs 提供的功能让插件构建更简单、让插件之间可以共享功能同时也作为集成者改变应用行为的一处定制点。每个 Utility API 由 TypeScript 接口以及一个用于访问实现的引用reference定义其实现由扩展定义与其他扩展一样可以被覆盖。路由RoutesBackstage 路由系统增加了一层间接性使插件无需显式知道其他扩展渲染在哪个 URL 路径、甚至无需知道其是否存在就能互相路由。它让插件可以互相共享路由、在运行时动态生成具体链接。链接到实际 URL 的解析由 App 负责集成者也可以定义自己的路由绑定来决定如何解析链接路由系统还支持插件定义内部路由便于在同一插件内链接到不同内容。后端构建块Backend Building Blocks后端架构图展示了各个构建块及其交互关系。后端实例Backend后端实例本身是部署单元自身不提供任何功能只负责接线。你可以决定部署多少个后端把所有功能放进单个后端或按扩展与隔离需求拆分为多个更小的部署。典型的后端入口代码如下对应仓库packages/backend-defaults中的createBackendimport { createBackend } from backstage/backend-defaults; import scaffolderPlugin from backstage/plugin-scaffolder-backend; // 创建后端实例 const backend createBackend(); // 安装所需功能 backend.add(import(backstage/plugin-catalog-backend)); // 功能也可以使用显式引用安装 backend.add(scaffolderPlugin); // 启动后端 backend.start();createBackend负责装配提供给应用的所有功能并为插件提供全部核心服务的默认实现。创建后端时不做实际工作一切延迟到backend.start()调用启动时后端会校验所有功能例如确保没有循环依赖。底层上createBackend调用backstage/backend-app-api的createSpecializedBackend后者负责在没有任何服务或功能的情况下真正创建后端实例——createBackend是开箱即用batteries included的高层入口createSpecializedBackend则更底层。仓库源码见 packages/backend-defaults/src/CreateBackend.ts。此外你可以在一个项目中创建多个后端例如只启用 catalog 插件的后端与只启用 scaffolder 插件的后端分开部署、独立扩容。后端插件Backend Plugins插件提供实际功能。它们完全独立运行若插件之间要通信只能通过网络进行不允许通过代码直接通信。因此每个插件都可以被视为一个独立的微服务。插件使用createBackendPlugin创建必须拥有与包名一致的pluginId去掉-backend后缀以及register方法// plugins/example-backend/src/plugin.ts import { coreServices, createBackendPlugin } from backstage/backend-plugin-api; export const examplePlugin createBackendPlugin({ pluginId: example, register(env) { env.registerInit({ deps: { logger: coreServices.logger }, async init({ logger }) { logger.info(Hello from example plugin); }, }); }, });插件生态遵循可扩展Scalable与隔离Isolated两条规则插件必须设计为可水平扩展不保存内存状态或确保状态可在多实例间复制通常存入外部服务如数据库插件绝不通过代码直接通信需要对外暴露接口时应通过 node-library 包导出 API 客户端服务。服务Services服务提供工具以简化插件的实现让每个插件不必从零实现一切。系统内置了大量核心服务日志、数据库访问、读取配置等也可以导入第三方服务或创建自己的服务。服务通过createServiceRef定义的引用 createServiceFactory定义的工厂实现构成一套依赖注入机制每个后端实例就是依赖注入容器。后端默认提供丰富的核心服务统一通过backstage/backend-plugin-api的coreServices命名空间访问例如Auth Service—— Token 认证与凭据管理Cache Service—— 用于缓存的键值存储Database Service—— 基于 Knex 的数据库访问与管理Discovery Service—— 插件间通信的服务发现Http Router Service—— 插件的 HTTP 路由注册Logger Service/Root Logger Service—— 插件级 / 根级日志Scheduler Service—— 分布式后台任务调度Url Reader Service—— 从外部系统读取内容Permissions Service、Metrics Service、Tracing Service等服务还作为后端安装的定制点你可以用自研实现覆盖服务也可以对现有服务做小幅定制。服务作用域默认是plugin每个插件获得独立实例另有root作用域跨插件共享、总是初始化。仓库中核心服务定义位于 packages/backend-plugin-api/src/services默认实现位于packages/backend-defaults。扩展点Extension Points许多插件提供了可扩展方式例如 Catalog 的实体提供者entity providers、Scaffolder 的自定义动作custom actions这些扩展模式现在被编码为扩展点Extension Points。扩展点看起来与服务类似同样通过引用依赖关键区别在于扩展点由插件或模块自己注册和提供取决于各自想暴露哪些定制扩展点从插件/模块实例中单独导出且可同时暴露多个——这样比维护单一庞大 API 表面更容易逐个演进和弃用。以 Scaffolder 的 actions 扩展点为例import { createExtensionPoint } from backstage/backend-plugin-api; export interface ScaffolderActionsExtensionPoint { addAction(action: ScaffolderAction): void; } export const scaffolderActionsExtensionPoint createExtensionPointScaffolderActionsExtensionPoint({ id: scaffolder.actions, });模块Modules模块使用扩展点向其他插件或模块添加新功能例如添加单个 Catalog 实体提供者、或一个或多个 Scaffolder 动作。每个模块只能使用属于单个插件的扩展点且必须与该插件部署在同一后端实例中模块只能通过注册的扩展点与其插件或其他模块通信。与插件一样模块也能访问服务并依赖自己的服务实现但它们与所扩展的插件共享服务——不存在模块专属的服务实现。模块创建示例如下为 Catalog 添加自定义处理器// plugins/catalog-backend-module-example-processor/src/module.ts import { createBackendModule } from backstage/backend-plugin-api; import { catalogProcessingExtensionPoint } from backstage/plugin-catalog-node; export const catalogModuleExampleCustomProcessor createBackendModule({ pluginId: catalog, moduleId: example-custom-processor, register(env) { env.registerInit({ deps: { catalog: catalogProcessingExtensionPoint, logger: coreServices.logger, }, async init({ catalog }) { catalog.addProcessor(new MyCustomProcessor(logger)); }, }); }, });模块初始化时序有严格保证为保证模块在插件启动前注册完所有扩展每个插件的所有模块会先于插件被完全初始化即所有模块init方法返回的 Promise 必须在插件init调用前 resolveinitresolve 之后便不能再与扩展点交互。数据库数据库承载 Backstage 数据。Backstage 后端及其内置插件基于 Knex 库并为每个插件建立独立的逻辑数据库从而获得良好的隔离性各插件可以独立执行迁移、独立演进。Knex 支持多种数据库但截至写作时 Backstage 主要针对两种进行测试SQLite—— 主要用作内存 mock/测试数据库PostgreSQL—— 首选的生产数据库其他数据库如 MySQL 系列据报可以工作但尚未被充分测试。为 Backstage 实例配置 PostgreSQL 的步骤见 Database为插件配置数据库见 Configuring Plugin Databases。插件架构三种形态从架构上看插件可以采取三种形态独立插件、服务后端插件、第三方后端插件。独立插件Standalone Plugins独立插件完全在浏览器中运行。例如 Tech Radar 插件只是渲染硬编码信息不向其他服务发起任何 API 请求。将 Tech Radar 安装进 Backstage 应用只需把它作为前端插件加入即可注以下示意图未展示前端和后端容器的详细内容以突出与添加指定插件相关的变更。插件添加完成后即可在 Backstage UI 中查看 Tech Radar 信息。服务后端插件Service Backend Plugins服务后端插件会向运行 Backstage 的组织职权范围内的服务发起 API 请求。例如 Lighthouse 插件向lighthouse-audit-service发起请求后者是一个运行 Google Lighthouse 库副本并把结果存入 PostgreSQL 数据库的微服务。Lighthouse 插件被添加到前端而lighthouse-audit-service容器已公开在 Docker Hub 上可下载并运行docker run spotify/lighthouse-audit-service:latestBackstage 中的软件目录是另一个服务后端插件示例它从 Backstage 后端服务检索一组服务实体并在表格中渲染给用户。第三方后端插件Third-party Backend Plugins第三方后端插件与服务后端插件类似主要区别在于支撑该插件的服务托管在托管 Backstage 的公司生态之外。CircleCI 插件即为一例CircleCI 是 SaaS 服务可完全不了解 Backstage 地独立使用它提供 API 供 Backstage 插件消费以展示内容。从用户浏览器发往 CircleCI 的请求会经过 Backstage 提供的代理服务proxy。若没有它这些请求会被跨域资源共享CORS策略拦截——CORS 会阻止托管在https://example.com的浏览器页面加载托管在https://circleci.com的资源。包架构Package ArchitectureBackstage 高度依赖 NPM 包既用于库的分发也用于项目内代码的组织。虽然如何组织 Backstage 项目由你决定但存在一组既定的推荐模式可帮助建立合理的项目结构并在不同 Backstage 项目间保持熟悉感。上图从单个插件及其可能包含的全部包粗边框、斜体字出发环绕插件的是不同的包组即插件的不同接口点。箭头表示对目标包代码的运行时依赖此严格依赖图仅适用于运行时dependencies为测试目的devDependencies可以打破该表的规则。app与backend包是 Backstage 项目的入口app包是把一组前端插件组装起来并按组织定制的应用backend包是为 Backstage 应用提供动力的后端服务。一个项目中可以有多个此类包尤其backend包可拆分为更小的部署单元各自服务自己的目的、承载更少的插件。插件包Plugin Packages一个典型插件由最多五个包组成两个前端包、两个后端包、一个 isomorphic同构包。插件内所有包必须共享公共前缀通常形如scope/plugin-plugin-idbackstage-plugin-plugin-id或scope/backstage-plugin-plugin-id也是合法变体。在前缀之外每个包还有标识其角色的唯一后缀。除这五个插件包外插件还可以有额外的前端/后端模块可安装以启用可选功能。完整后缀清单与角色说明见 Plugin Package Structure ADR。-react、-common、-node三个插件包共同构成插件的外部库plugin library。插件库让其他插件可以在此基础上构建和扩展本插件也让本插件能够依赖和扩展其他插件。因此插件库包应当允许被重复安装版本混装很常见插件也禁止直接导入其他插件的非库包插件间的所有通信都必须通过库和应用本身进行。前端包Frontend Packages前端包分为两大组。第一组是 Frontend App Core即仅由app包使用的一组包帮助搭建应用核心结构并为插件库提供可依赖的基础。第二组是其余共享包进一步分为 Frontend Plugin Core 与 Frontend Libraries核心包被认为特别稳定构成前端框架的核心其最重要职责是围绕每个插件形成边界并提供把一组插件组合成运行中应用的工具集其余前端包是更传统的库作为构建插件的积木。后端包Backend Packages后端库包目前并不像前端包那样共享类似的插件架构它们只是一组帮助构建后端服务的积木与模式。不过这一状况未来很可能改变。公共包Common Packages公共包是事实上被所有其他包依赖的包数量小但渗透性强。由于公共包是同构isomorphic的、必须在前端和后端都能执行它们永远不允许依赖任何前端或后端包。Backstage CLI 自成一类几乎被所有其他包依赖但它本身不是库必须始终只是开发依赖devDependency。如何决定代码放置位置有时很难决定插件代码放在哪里——例如应该直接放在-backend插件包中还是-node包中通用准则是尽量降低代码的暴露程度。如果不必成为公共 API就最好不要暴露如果不需要被其他插件使用就把它直接放在插件包里。缓存CacheBackstage 后端及其内置插件还可以利用缓存存储来提升性能或可靠性。与数据库类似插件会获得逻辑隔离的缓存连接底层由 Keyv 驱动。截至写作时Backstage 可配置使用五种缓存存储之一store 取值适用场景memory主要用于本地开发memcache生产部署选项之一redis生产部署选项之一valkey生产部署选项之一infinispan生产部署选项之一memory主要用于本地开发生产部署推荐使用其余存储之一。哪种缓存存储适合你的 Backstage 实例取决于你自己的运行时约束以及所运行插件的需求。使用 memory 作为缓存backend: cache: store: memory使用 memcache 作为缓存backend: cache: store: memcache connection: user:passcache.example.com:11211使用 Redis 作为缓存backend: cache: store: redis connection: redis://user:passcache.example.com:6379使用 Infinispan 作为缓存最小配置全部使用默认值不配置authentication期望缓存名为cache、主机为127.0.0.1:11222backend: cache: store: infinispan扩展配置与 Redis 不同Infinispan不会自动创建缓存——需要你预先在 infinispan 服务器中配置好缓存。完整的配置项列表包括备份集群支持参见 Infinispan HotRod JavaScript 客户端 API 文档backend: cache: store: infinispan infinispan: servers: - host: 127.0.0.1 port: 11222 cacheName: backstage-cache mediaType: application/json authentication: enabled: true userName: yourusername password: yourpassword saslMechanism: PLAIN欢迎贡献对其他缓存存储的支持。小结Backstage 的架构可以用三个组件、两套构建块、一条插件主线来概括Core/App/Plugins 三大组成划分了职责边界前端以应用扩展树为核心通过扩展、Utility API 与路由系统实现插件间的组合与间接通信后端以独立插件为微服务单元通过服务依赖注入与扩展点模块扩展实现解耦与定制数据库基于 Knex 按插件逻辑隔离缓存基于 Keyv 支持五种存储。插件三种形态独立、服务后端、第三方后端决定了其部署与网络边界而 NPM 包架构则为代码组织提供了低暴露、按角色分包的明确指引。理解这些构建块是规划多后端拆分、编写新插件、为生产环境落地 Backstage 的第一步。【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考