十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Backstage 生产环境扩容实战指南:水平扩展、后端拆分与前端分离

Backstage 生产环境扩容实战指南:水平扩展、后端拆分与前端分离 Backstage 生产环境扩容实战指南水平扩展、后端拆分与前端分离【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage本指南面向 Backstage 运维人员Admins系统讲解当组织规模增长、插件数量增多后如何对 Backstage 部署进行扩容。你将掌握三条由浅入深的扩容路径通过负载均衡水平扩展多副本、将后端按插件拆分到多个服务、以及将前端静态资源从后端独立出来交给 CDN 或 NGINX 托管并学会用指标信号判断何时该扩容。扩容的整体思路单台 Backstage 实例可以很好地服务大量用户但当组织持续增长、接入的插件越来越多时单实例的 CPU、内存和数据库连接都会成为瓶颈。Backstage 的扩容策略由简到繁共有三个层次本指南007-scaling.md以及配套的完整参考文档Scaling Backstage Deployments覆盖了全部方案水平扩展Horizontal scaling部署多台完全相同的实例用负载均衡分发请求拆分后端Splitting the backend将不同插件拆到多个独立的后端服务中分别部署和扩容分离前端Separating the frontend把前端静态资源从后端中剥离独立构建、独立托管。实践建议是先做水平扩展它最简单且能应对绝大多数增长场景只有在水平扩展不够用时再考虑更复杂的后端拆分。水平扩展多副本 共享外部资源水平扩展是最直接的扩容方式运行多台完全相同的 Backstage 实例把它们放在负载均衡器后面。所有实例共享同一个外部数据库以及可选的缓存、搜索服务Backstage 的后端插件会通过数据库进行协调——共享状态、分发任务因此实例之间天然一致。在 Kubernetes 中水平扩展只需要修改 Deployment 的副本数spec: replicas: 3不需要任何额外配置协调工作完全由数据库承担。这背后依赖的关键前提是实例必须是无状态的所有需要持久化的数据catalog 实体、scaffolder 任务、用户设置等都落在共享的外部资源上而不是本地磁盘。该路径与 Golden Path 部署系列 中的数据库步骤002-database.md衔接紧密——只有将数据库外置如 PostgreSQL后多副本共享同一数据源才成为可能。何时应该扩容关注这几类信号不要等到用户体验恶化才扩容。官方文档给出了四类典型信号信号说明API 响应时间持续上升后端处理能力接近饱和Catalog 处理进度落后可通过catalog.processing.duration指标观察Scaffolder 任务排队时间超出预期任务积压意味着执行能力不足用户反馈页面加载变慢前端渲染或后端 API 均可能成为瓶颈其中catalog.processing.duration指标有明确的源码依据它在 DefaultCatalogProcessingEngine.ts 中以直方图Histogram形式创建描述为 Time spent executing the full processing flow执行完整处理流程所花费的时间单位是秒在处理流程结束时代码会按result: unchanged、result: errors、result: changed三种结果分别记录耗时见 L455-L471。同一文件还暴露了其他有用的处理指标例如catalog.processed.entities.count已处理实体数量计数L396-L399catalog.processors.duration执行 catalog 处理器的耗时直方图catalog.processing.queue.delay从任务被调度到实际开始处理的排队延迟。这些指标配合 监控章节 介绍的 OpenTelemetry 采集方案Prometheus 采集指标、OTLP 上报链路可以配置告警来捕获处理积压或scaffolder 运行异常缓慢等情况。拆分后端按插件划分独立服务对于更大规模的部署可以把后端拆成多个服务每个服务运行不同的插件集合。例如将 catalog 和 scaffolder 拆成两个独立部署这样 catalog 的重型处理就不会拖累 scaffolder 的性能。这是一个更高级的方案官方文档明确了三个硬性要求独立的后端包每个后端包只 import 自己需要的插件自定义DiscoveryService实现按插件 ID 把请求路由到正确的后端合理的路由同时处理好外部ingress和内部backend 到 backend流量。详细的搭建步骤见 backend system 文档Split Into Multiple Backends一节。创建独立后端包目前yarn new没有后端包模板最快的办法是复制现有packages/backend包再修改。目录结构可以这样组织packages/ backend-a/ src/ index.ts package.json - name: backend-a backend-b/ src/ index.ts package.json - name: backend-b拆分时只需要把每个包的src/index.ts裁剪为各自需要的插件。以当前仓库的 packages/backend/src/index.ts 为参照——它注册了 auth、app、catalog、scaffolder、techdocs、search、signals、notifications 等大量插件——如果你想拆出 scaffolderbackend-a可以精简为import { createBackend } from backstage/backend-defaults; const backend createBackend(); backend.add(import(backstage/plugin-app-backend)); backend.add(import(backstage/plugin-catalog-backend)); backend.add( import(backstage/plugin-catalog-backend-module-scaffolder-entity-model), ); backend.start();backend-b则只包含 scaffolder记得同步清理package.json中不再使用的依赖import { createBackend } from backstage/backend-defaults; const backend createBackend(); backend.add(import(backstage/plugin-scaffolder-backend)); backend.start();让多个后端互相通信DiscoveryService拆成多个后端后最繁琐的部分是让它们能互相通信。Backstage 目前没有开箱即用的解决方案你需要为每个后端提供自定义的DiscoveryService实现让它们能返回彼此正确的 URL在前端提供自定义的DiscoveryApi实现除非你用反向代理统一处理路由。DiscoveryService接口定义在 packages/backend-plugin-api/src/services/definitions/DiscoveryService.ts包含两个方法getBaseUrl(pluginId)返回某个插件的内部HTTP 基地址无尾部斜杠用于 Backstage 后端实例之间的服务到服务通信例如http://10.1.2.3/api/cataloggetExternalBaseUrl(pluginId)返回某个插件的外部基地址要求从前端及其他外部服务可达、且保持稳定例如https://backstage.example.com/api/catalog可用于回调或 Webhook URL。接口的文档注释特别强调getBaseUrl必须在每次发起请求前调用而不是在构造 API client 时取一次缓存这样才能支持更灵活的路由模式不同时刻可能返回不同结果。实现可以简单到基于 pluginId 拼接 URL 模板也可以为个别插件提供覆盖甚至查询独立的发现服务。拆分后端的架构示例backstage 官方仓库的 backend system 文档给出了一个三后端部署的架构示例图在这个示例中Catalog 和 Search 插件被拆到一个后端代理把所有/api/catalog/和/api/search/流量路由到该实例从而可以独立扩缩容和部署同时在性能与安全上实现隔离TechDocs 和 Scaffolder 插件拆到另一个后端其余流量App、Auth、Proxy 插件路由到第三个实例。图中还体现了每个插件拥有自己的逻辑数据库、但通常共享同一个 DBMS 实例的做法——这并非强制要求你可以按需进一步拆分或合并数据库。分离前端从后端剥离静态资源默认情况下前端由后端部署通过backstage/plugin-app-backend插件直接托管见当前仓库 packages/backend/src/index.ts 中的backend.add(import(backstage/plugin-app-backend))以及 Docker 构建说明 中前端由后端内置的 app-backend 插件托管的描述。如果你需要减轻后端负载或希望把前端放到 CDN 上以获得更好的访问性能可以单独部署前端具体分三步从后端移除backstage/plugin-app-backend插件把前端构建为静态 bundleyarn workspace app build产物位于packages/app/dist用独立容器例如 NGINX或静态托管服务来承载这些静态文件。分离前端的一个关键注意事项:::note 配置注入方式的改变 当前端单独托管时配置不再由后端在运行时注入。必须在前端构建时提供正确的配置通过--config参数指定配置文件列表因为配置会被嵌入到实际的静态 JavaScript 文件中。 :::这与原来后端运行时注入配置的模式有本质区别是分离前端时最容易踩的坑。官方提供的 NGINX 方案仓库的 contrib/docker/frontend-with-nginx 目录提供了完整可用的 Docker 方案包含两个变体Dockerfile.dockerbuild在 Docker 内部先构建再打包适合不想在宿主机装 Node 工具链的场景Dockerfile.hostbuild在宿主机或 CI完成构建Docker 只负责拷贝产物构建更快、缓存更好。两者的最终运行镜像一致都基于nginx:mainline并将前端产物放到/usr/share/nginx/html。使用方式以 dockerbuild 为例将Dockerfile.dockerbuild和docker/目录复制到项目根目录在.dockerignore中确保源码目录未被排除但排除node_modules和构建产物修改 Dockerfile 中的构建命令追加配置参数RUN yarn workspace app build --config config1 --config config2 ...在项目根目录执行docker build -t backstage-frontend -f Dockerfile.dockerbuild .Dockerfile.dockerbuild的构建阶段使用node:20-buster先yarn install再yarn workspace app build随后把packages/app/dist拷贝进 NGINX 镜像并挂载 docker/default.conf.template 与 docker/inject-config.sh。该 NGINX 配置通过模板声明式端口listen $PORT;默认 80对/使用try_files $uri /index.html支持前端路由回退并额外提供一个/healthcheck端点返回 204方便接入 Kubernetes 存活探针。值得一提的是inject-config.sh脚本它模仿backstage/config-loader的读取方式从以APP_CONFIG_开头的环境变量中构建运行时配置 JSON并通过查找静态包内__APP_INJECTED_RUNTIME_CONFIG__占位符、用 sed 将其替换为实际配置。这意味着即使在前端单独托管模式下你依然可以在容器启动时通过环境变量注入运行时配置而无需重新构建镜像——这是对构建时注入限制的一个重要补充手段。更进一步多区域复制除上述方案外官方文档还提到了跨区域复制multi-region replication将 Backstage 部署复制到多个区域。需要明确的是Backstage 对此没有内置支持这种模式通常只对个别后端插件而非整个应用有意义实施前需要自行评估成本与收益。参考与延伸阅读完整扩容参考文档docs/deployment/scaling.md后端拆分详细教程backend system - Split Into Multiple Backends后端服务定义DiscoveryService 接口源码前端独立托管示例contrib/docker/frontend-with-nginx指标与监控Golden Path - Monitoring your deployment部署系列入口Golden Path - Deploying Backstage to production【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表