2. Backstage 核心架构:App、Plugin、Backend、Frontend 的分层与通信机制
理解 Backstage 的架构分层是设计插件隔离策略的前提。Backstage 采用 前端-后端分离 的微内核架构,核心实体包括 App(应用壳)、Plugin(插件)、Frontend(前端模块) 和 Backend(后端服务)。这四个层次通过明确的契约和通信机制协同工作,为容量规划中的故障域隔离提供了天然的结构基础。
2.1 四层架构总览
下图展示了 Backstage 的核心分层结构及各层之间的通信路径。每一层都承担独立的职责,并通过标准接口进行交互。
架构要点:App Shell 不包含业务逻辑,仅作为插件容器。每个 Plugin 在前后端都有对应的模块,形成“一对插件对”。这种设计使得单个插件的故障可以被限制在其自身的前后端范围内,不会扩散到整个系统。
2.2 各层职责详解
| 层次 | 核心职责 | 关键技术 | 故障域范围 |
|---|---|---|---|
| App Shell | 插件注册、路由分发、全局 UI 框架、主题系统 | React Router、Context API、Dynamic Import | 全局(崩溃影响所有插件) |
| Frontend Plugin | UI 渲染、用户交互、前端路由、状态管理 | React、Material UI、Zustand/Redux | 插件级(崩溃仅影响该插件页面) |
| Backend Plugin | 业务逻辑处理、数据持久化、外部系统集成 | Express/Koa、gRPC、Prisma/TypeORM | 服务级(崩溃影响该插件后端功能) |
| 基础设施层 | 数据库、缓存、消息队列、外部 API | PostgreSQL、Redis、Kafka | 数据级(故障影响所有依赖该资源的插件) |
2.3 前后端通信机制
Backstage 的前端插件与后端插件之间通过 标准化的 API 代理 进行通信,而不是直接调用。这种机制是实现插件隔离的关键。
- API 代理(Proxy):App Shell 内置一个反向代理,将前端发往
/api/{pluginId}/*的请求转发到对应的后端插件服务。 - 服务发现:后端插件启动时向 App Shell 注册自己的服务地址和路由前缀,前端无需感知后端的具体部署位置。
- 通信协议:默认使用 RESTful HTTP/JSON;对于高性能场景,Backstage 也支持通过 gRPC 进行后端插件间的通信。
// 前端插件调用后端 API 的典型模式
// 使用 @backstage/core-plugin-api 提供的 createApiRef 和 fetchApi
import { createApiRef, useApi } from '@backstage/core-plugin-api';
// 1. 定义 API 引用(契约)
export const myPluginApiRef = createApiRef<MyPluginApi>({
id: 'plugin.my-plugin.service',
});
// 2. 实现 API 客户端(自动通过代理转发)
class MyPluginClient implements MyPluginApi {
constructor(private readonly fetchApi: { fetch: typeof fetch }) {}
async getData(id: string): Promise<MyData> {
// 请求自动被代理到后端插件的 /api/my-plugin/data/{id}
const response = await this.fetchApi.fetch(`/api/my-plugin/data/${id}`);
return response.json();
}
}
// 3. 在 React 组件中使用
const MyComponent = () => {
const client = useApi(myPluginApiRef);
// client.getData(...) 触发跨层通信
};
隔离性分析:由于所有前端请求都经过 App Shell 的代理层,后端插件的地址变更、服务重启、甚至崩溃都不会直接影响前端插件的加载。前端插件只会收到 HTTP 错误响应(如 503),而不会导致整个页面崩溃。这为容量规划中的“故障域隔离”提供了第一道防线。
2.4 插件间的依赖与隔离
在 Backstage 中,插件之间允许存在依赖关系,但必须通过 显式接口 进行。这种设计避免了隐式耦合,使得每个插件的故障域可以被清晰界定。
容量规划警示:虽然插件间通过显式接口通信,但在容量规划中,如果 Plugin A 对 Plugin B 的依赖是同步且高频率的,那么 Plugin B 的容量瓶颈会直接传导至 Plugin A。在划分故障域时,应将这种强依赖的插件对视为一个“容量组”,避免将它们部署在完全独立的资源池中导致延迟放大。
2.5 分层架构对故障域隔离的启示
- 进程级隔离:每个后端插件可以独立部署为单独的进程或容器,实现操作系统级的故障域隔离。
- 通信级隔离:通过 API 代理和超时/熔断机制,防止后端故障无限期阻塞前端线程。
- 数据级隔离:每个后端插件应拥有独立的数据库 Schema 或数据库实例,避免数据层面的级联故障。
- 部署级隔离:在 Kubernetes 环境中,可以将不同插件部署到不同的 Node 或 Availability Zone,实现物理故障域隔离。