2026 年多仓库微服务文档聚合策略:Docs-as-Code + Docusaurus 统一门户
目录
在大规模微服务平台中,文档治理往往比架构设计本身更容易失控。Confluence、Notion 等中心化 wiki 工具在团队规模扩大后,很容易出现"文档漂移"(documentation drift)——文档与实际代码脱节,没人确定哪个版本更接近现状。
最近给自己的微服务项目搭文档站,选了 Docs-as-Code 这条路——文档和代码放同一个仓库,每个服务维护自己的 /docs/,最后用 Docusaurus 聚合成一个统一的门户。
这种模式和 Domain-aligned multi-repo 架构(每个 domain 有独立的 MS/BFF/consumer)比较契合:service owner 维护自己的 ADR 和设计文档,文档也更贴近代码;同时再通过 Docusaurus 提供统一入口。它和 Team Topologies 里 Stream-Aligned Team 的自治原则也比较一致。
这篇文章整理的是一套目前可落地的方案:组织结构、各服务 /docs/ 内容规范、Docusaurus 聚合机制、ADR 落地,以及我调研时看到的几种开源方案。
整体架构:三种仓库角色#
在多仓库微服务平台中,文档体系涉及三种仓库角色:
中央架构仓库"] -->|聚合| B["platform-docs
Docusaurus 统一文档站"] C["MS repo"] -->|/docs/| B D["BFF repo"] -->|/docs/| B E["Consumer repo"] -->|/docs/| B
三种仓库的职责分工:
| 仓库类型 | 示例 | 文档职责 |
|---|---|---|
| 中央架构仓库 | platform-architecture |
全局架构概览、跨域决策、平台级 ADR、共享关注点(Kafka/Redis/Observability) |
| 服务仓库 | order-ms、user-bff |
服务内部设计、服务级 ADR、API contract、Kafka 事件 schema、数据库 schema |
| Docusaurus 文档站仓库 | platform-docs |
聚合所有来源的 Markdown,构建统一文档站(部署到 Vercel/Netlify) |
这种分工的关键好处是:service owner 只需要维护自己 repo 的 /docs/,平台团队负责聚合和样式一致性。文档不一定会自动变好,但至少更不容易和代码长期脱节。
部署选项:中央架构仓库与文档站是否合并#
上面画的是三种仓库的逻辑角色。实际部署时,中央架构仓库和 Docusaurus 文档站仓库可以选择合并为一个 repo,也可以分开。这是两种常见的部署策略:
选项 A:分开两个 repo(我目前更常想到的起点)#
中央架构仓库(platform-architecture)和文档站仓库(platform-docs)独立存在,platform-docs 通过 docusaurus-plugin-remote-content 或 CI 同步脚本从 platform-architecture 拉取文档。
适用场景:架构文档的审阅者和文档站的技术栈维护者是不同的人/团队。平台团队可以独立演进 Docusaurus 版本、主题、插件,不影响架构文档本身。
选项 B:合并为一个 repo(更适合小团队)#
把 Docusaurus 项目直接放进中央架构仓库,两者共用一个 repo。文档源就是 Docusaurus 的 docs/ 目录,不需要额外的远程拉取或同步脚本。
platform-architecture/
├── docs/ # Docusaurus 文档源(就是中央架构文档本身)
│ ├── overall/
│ ├── adrs/
│ ├── cross-cutting/
│ └── services/ # 从各服务 repo 聚合来的文档(CI 同步)
├── docusaurus.config.ts # Docusaurus 配置
├── sidebars.js
├── package.json
├── src/ # Docusaurus 自定义组件(如有)
├── README.md
└── .github/workflows/
└── deploy.yml # PR Preview + Vercel/Netlify 部署
这种布局下,docs/overall/、docs/adrs/、docs/cross-cutting/ 本身就是仓库的固有内容,不需要"远程拉取"。只有 docs/services/ 目录需要通过 CI 从各服务仓库同步过来。
适用场景:小团队或单人项目,架构文档和文档站维护者是同一人,不需要区分两个 repo 的权限边界。CI 流程更简单——一次 push 就能同时更新文档内容和触发站点 rebuild。
两种选项的核心区别只在于中央架构文档是否需要被"拉取"到另一个 repo 才能构建。服务仓库的 /docs/ 规范、聚合机制、ADR 流程完全一样。
中央架构仓库的内容组织#
中央架构仓库(例如 platform-architecture)存放跨域文档和平台级决策。下面这套目录布局更适合作为起点:
platform-architecture/
├── docs/
│ ├── overall/ # 总体架构
│ │ ├── architecture-overview.md
│ │ ├── domain-ownership.md
│ │ ├── glossary.md
│ │ └── request-lifecycle.md
│ ├── adrs/ # 全局 ADR(平台级决策)
│ │ ├── 0001-use-oceanbase-per-domain.md
│ │ ├── 0002-kafka-outbox-pattern.md
│ │ └── template.md
│ ├── cross-cutting/ # 共享关注点
│ │ ├── kafka-guidelines.md
│ │ ├── redis-guidelines.md
│ │ ├── observability.md
│ │ └── security.md
│ └── sidebar.js # 全局侧边栏配置片段
├── README.md
└── .github/workflows/ # 可选:触发 docs 站 rebuild 的 dispatch
这个仓库的内容包括:
- 架构概览:C4 Model 的 System Context 和 Container 级别图,描述所有 domain 的边界和交互
- Domain 归属:每个业务域归哪个团队负责、SLO 目标是什么
- 平台级 ADR:影响全局的架构决策(例如"每个 domain 使用独立 OceanBase 实例"、“跨域通信统一使用 Kafka outbox pattern”)
- 共享关注点:Kafka 使用规范、Redis key namespace 策略、Observability 平台接入、安全基线
服务仓库的 /docs/ 目录规范#
每个服务仓库(无论是 *-ms、*-bff、还是抽离的 *-mc)的 /docs/ 目录,如果能尽量遵循一套相对统一的结构,会更方便 service owner 维护,也更有利于 Docusaurus 聚合后形成一致、可搜索的统一文档站。
一套可参考的 /docs/ 目录结构#
docs/
├── index.md # 服务概览入口(必须)
├── architecture.md # 整体架构设计(C4 图、数据流)
├── adrs/ # 架构决策记录(必须,每项决策一个文件)
│ ├── 0001-transactional-outbox.md
│ ├── 0002-oceanbase-schema-design.md
│ └── template.md # 复制模板用
├── api/ # API 相关
│ └── endpoints.md # 关键端点说明 + 使用示例 + OpenAPI 文档入口
├── kafka/ # 事件相关(MS 和 mc 必备)
│ ├── published-events.md # 本服务发布的事件 schema + 版本
│ ├── subscribed-topics.md # 订阅的 topic + 处理逻辑
│ └── consumer-groups.md # consumer group 配置与 scaling
├── database/ # 数据层(仅 MS)
│ ├── schema-overview.md
│ ├── liquibase-strategy.md
│ └── key-tables.md
├── bff-specific/ # 仅 Player/Backoffice BFF 需要
│ ├── aggregation-logic.md
│ ├── mobile-optimization.md # Player BFF 专用
│ └── bulk-operations.md # Backoffice BFF 专用
├── dependencies.md # 外部依赖与调用关系
├── observability.md # 监控、日志、tracing 配置
├── deployment.md # K8s manifests、scaling、SLO
├── troubleshooting.md # 常见问题 & 排查指南
├── diagrams/ # 存放 Mermaid / PlantUML 源文件(可选)
└── _category_.json # Docusaurus 侧边栏元数据(推荐)
每个核心文件应该包含的内容#
index.md(服务首页,必备)#
服务概览入口,包含:
- 服务全称、owner/team(GitHub
CODEOWNERS对应) - 简短职责描述(一句话对齐业务域)
- 关键指标:SLO、吞吐目标、延迟 P99
- 在整体架构中的位置(简短链接到中央架构 repo)
- 快速导航到其他文档 section
示例结构:
# order-ms
- **Owner**: Order Team ([CODEOWNERS](./CODEOWNERS))
- **职责**: Order domain 的核心业务逻辑、数据持久化、事件发布
- **SLO**: 99.9% availability, P99 latency < 200ms
- **架构位置**: 参见 [Domain Ownership](link-to-central-arch)
## 快速导航
- [架构设计](./architecture.md)
- [ADR 决策记录](./adrs/)
- [API contract](./api/)
- [Kafka 事件](./kafka/)
architecture.md#
- C4 Model 图:Context → Container → Component 级别(用 Mermaid 绘制)
- 数据流与调用链(Frontend → BFF → 本 MS → 其他 MS / Foundation Engine)
- 关键技术栈(Java 25 + Spring Boot 3.5 / Golang、高性能点如 WebFlux)
- 与统一认证中心的集成方式(不同 auth context、权限传递)
Docusaurus 原生支持 Mermaid,可以直接在 Markdown 中绘制:
```mermaid
graph TD
A[Frontend BFF] -->|HTTP/gRPC| B[Order MS]
B -->|Kafka| C[Loyalty MS]
B -->|Kafka| D[Wallet MS]
B -->|Read| E[(OceanBase)]
```
adrs/(我更倾向采用 MADR 模板)#
每份 ADR 记录一次架构决策,采用 MADR(Markdown Architectural Decision Records)标准格式:
# ADR-0001: Use Transactional Outbox for Cross-Domain Events
## Status
Accepted
## Context
跨域事件需要保证与本地事务的一致性...
## Decision
采用 Transactional Outbox pattern,通过 Debezium CDC 同步到 Kafka...
## Alternatives
- 双写模式(应用层同时写 DB 和 Kafka)
- 事件溯源(Event Sourcing)
## Consequences
- 好处:保证 exactly-once 语义
- 代价:需要维护 outbox 表 + Debezium connector
如果团队愿意把 ADR 检查放进 PR 模板,涉及架构变更的 PR 就可以在 docs/adrs/ 下新增或更新 ADR。这更符合 You Build It You Run It 的思路,也更有助于减少文档漂移。
api/ 与 kafka/(高性能系统关键)#
api/ 目录:
- OpenAPI 规范 + 关键端点语义、请求/响应示例、版本兼容策略
- contract library 使用说明
kafka/ 目录:
- 事件 schema(Avro/JSON Schema)、exactly-once 保证
- dead-letter 策略、replay 机制
- consumer group 配置与 scaling 策略
特别适合 payment/ecommerce 场景:强调幂等性、事务边界、补偿机制。
database/(仅 Domain MS)#
- Schema 演进策略(例如 Liquibase 的演进约定)
- 数据所有权边界(只写本域表)
- 快照/denormalization 策略(通过 Kafka 事件维护)
dependencies.md#
- 上游/下游服务调用列表(只允许 upper → foundation)
- 同步调用(Feign / RestClient)与异步(Kafka)比例
- 电路熔断、重试、bulkhead 配置(Resilience4j / Golang 对应库)
observability.md#
- OpenTelemetry 配置、指标暴露、日志结构、tracing 采样率
- 告警规则与 SLO 定义(与平台团队对齐)
deployment.md(K8s / Cloud Native 重点)#
- Deployment / HPA / PDB 配置
- 资源请求与 limit(高性能调优经验)
- 滚动更新策略、canary 发布
不同服务类型的侧重点#
| 服务类型 | 示例 | 侧重内容 |
|---|---|---|
| Domain MS | order-ms、user-ms |
business rules、transaction boundaries、data ownership、Kafka in/out |
| Frontend BFF | frontend-bff |
mobile latency optimization、response shaping、caching 策略、trusted headers 处理 |
| Backoffice BFF | backoffice-bff |
bulk operations、search/query optimization、admin audit logging、异步 job 导出 |
| Standalone Consumer | *-mc |
scaling 原因、独立 consumer group、处理吞吐、错误重试与 dead-letter 机制 |
| Foundation Engine | wallet-ms |
one-way dependency 严格执行、底层性能特性(R2DBC 等) |
Docusaurus 统一文档站#
platform-docs 是一个独立的 Docusaurus 3.x 项目,可以部署在 Vercel 或 Netlify(支持 PR Preview)。它的核心任务是聚合所有来源的 Markdown,形成统一、可搜索的文档门户。
docusaurus.config.ts 核心配置#
// docusaurus.config.ts
import { themes } from 'prism-react-renderer';
export default {
title: '平台架构文档站',
url: 'https://example.com',
baseUrl: '/',
presets: [['@docusaurus/preset-classic', {}]],
plugins: [
// 1. 中央架构文档(本地)
[
'@docusaurus/plugin-content-docs',
{
id: 'overall',
path: 'docs/overall',
routeBasePath: '/overall',
sidebarPath: require.resolve('./sidebars/overall.js'),
},
],
// 2. 全局 ADR
[
'@docusaurus/plugin-content-docs',
{
id: 'adrs',
path: 'docs/adrs',
routeBasePath: '/adrs',
sidebarPath: require.resolve('./sidebars/adrs.js'),
},
],
// 3. 服务级文档(远程聚合)
[
'docusaurus-plugin-remote-content',
{
sources: [
{
name: 'order-ms',
url: 'RAW_ORDER_MS_DOCS_URL',
pattern: '**/*.md',
},
{
name: 'frontend-bff',
url: 'RAW_FRONTEND_BFF_DOCS_URL',
pattern: '**/*.md',
},
// ... 所有 domain 服务(可通过 repositories.json 动态加载)
],
destination: 'docs/services',
},
],
],
themeConfig: {
prism: { theme: themes.github, darkTheme: themes.dracula },
navbar: {
title: 'Platform Docs',
items: [
{ to: '/overall/intro', label: '总体架构', position: 'left' },
{ to: '/adrs/global', label: 'ADR 决策', position: 'left' },
{ to: '/services', label: '服务文档', position: 'left' },
],
},
},
};
侧边栏配置(sidebars.js)#
// sidebars/main.js
module.exports = {
main: [
{ type: 'doc', id: 'overall/intro' },
{
type: 'category',
label: '业务域',
items: [
{
type: 'category',
label: 'Order',
items: [
'services/order-ms/index',
'services/order-ms/architecture',
'services/frontend-bff/index',
],
},
// ... 动态生成
],
},
{
type: 'category',
label: 'ADR 决策记录',
items: ['adrs/global', 'services/*/adrs/**'],
},
],
};
聚合机制方案对比#
我调研时最常见的三种方案:
方案 A(我目前更倾向):docusaurus-plugin-remote-content
- 专为 multi-repo 设计,已被广泛用于微服务文档聚合
- 在 docusaurus build 前自动从各 repo raw URL 下载最新 MD 文件
- 支持 pattern 过滤、缓存
- 社区里资料相对多,便于快速起步
方案 B(更强 CI 控制):GitHub Actions 同步脚本
- 每个服务 PR 合并后,通过
repository_dispatch触发platform-docsrebuild - clone 所有
/docs/到临时目录,再yarn build - 完整控制流程,适合对安全性要求高的组织
方案 C:Docusaurus 多实例(multi-instance)+ 自定义 preset
- 实现 overall / services 分离但统一导航
- 适合大型组织需要严格隔离文档源的场景
对多数团队来说,方案 A 往往是上手成本最低的选择。如果已经有比较完善的 CI/CD 基础设施,方案 B 会给你更多可控性。
CI/CD & 治理机制#
文档治理不只是写 Markdown,更需要一套 GitOps 风格的自动化流程。
GitOps 工作流#
关键环节:
-
PR 模板强制检查:每个服务仓库的 PR 模板包含 checklist
- 更新了
docs/adrs/吗? -
index.md是否反映了变更? - API 变更是否同步了
openapi.yaml?
- 更新了
-
GitHub Actions 触发链:服务 repo 合并 →
repository_dispatch→platform-docsrebuild -
Vercel Preview:文档站每次 build 生成预览 URL,贴在 PR 评论中供 review
服务 Owner 与平台团队的责任边界#
| 角色 | 责任 |
|---|---|
| Service Owner | 维护自己 repo 的 /docs/(内容准确性、ADR、架构图) |
| Platform Team | 维护 platform-docs 和同步 workflow、样式一致性、搜索/版本化基础设施 |
| 架构团队 | 维护中央架构仓库(跨域文档、平台级 ADR) |
这种分工能保留 service owner 的自治性,同时让文档更容易跟随代码更新、支持版本控制和 PR review,也减少了手工复制的成本。
ADR 机制详解#
ADR(Architectural Decision Record)是文档治理的核心构件。它记录的不仅仅是"最终决定",而是决策的上下文、备选方案和后果。
MADR 模板#
采用 MADR(Markdown Architectural Decision Records)标准模板:
# ADR-NNNN: 决策标题
## Status
Proposed | Accepted | Deprecated | Superseded
## Context
描述做出这个决策的背景信息。包括技术约束、业务需求、现有方案的问题等。
## Decision
清晰描述做出的决策。用简洁的语言说明选择了什么方案。
## Alternatives
列出考虑过的备选方案,以及为什么没有选择它们。
- 备选方案 1:描述 + 不选原因
- 备选方案 2:描述 + 不选原因
## Consequences
这个决策带来的影响(正面和负面)。
- 正面:...
- 负面:...
## Related
- 相关的 ADR 链接
- 相关文档链接
ADR 编号策略#
两种常见方式:
- 全局唯一编号(e.g.
ADR-001):适合平台级决策,所有服务共享编号空间 - Per-Service 编号(e.g.
player-ms/ADR-001):适合服务内部决策,每个服务独立编号
按我目前的理解,混合模式会更顺手:中央架构仓库用全局编号,各服务仓库用 per-service 编号。Docusaurus 中统一展示为可搜索列表 + 状态标签(Proposed / Accepted / Deprecated)。
PR 强制检查#
在 .github/PULL_REQUEST_TEMPLATE.md 中添加:
## 文档更新检查
- [ ] 本次变更是否需要在 `docs/adrs/` 中新增/更新 ADR?
- [ ] `docs/index.md` 是否反映了最新的服务状态?
- [ ] API/Kafka schema 变更是否已同步 `docs/api/` 和 `docs/kafka/`?
这确保了文档更新不是"有空再做"的可选事项,而是 PR 合入的前置条件。
2026 年开源项目与公司实践#
开源插件与工具#
- docusaurus-plugin-remote-content:社区里常见的远程内容聚合插件,支持从 GitHub raw URL 自动下载 Markdown 并过滤 pattern。npm 包名为
@crossid/docusaurus-remote-content。 - Building Centralized Documentation Across Microservices with Docusaurus(Piotr Pomierski):完整的 CI 驱动文档聚合实践,用 GitLab CI 定时从各微服务仓库拉取文档,提交到中央 Docusaurus 仓库自动构建部署。
- Docusaurus 官方 Multi-instance 文档:
@docusaurus/plugin-content-docs原生支持多实例,允许在同一站内运行多个独立的 docs 集合(例如/overall、/adrs、/services各自独立导航)。
ADR 标准与工具#
- MADR(Markdown Architectural Decision Records):由 adr/madr 维护的 ADR 标准模板,包含完整版和最小版两种。被广泛用于各类项目的架构决策记录。
- ADR GitHub Organization:Michael Nygard 提出的 ADR 概念在 GitHub 上的官方聚合站,包含多种 ADR 模板和工具链。
其他方案对比#
- Antora:专为 multi-repo 文档设计的静态站生成器,支持多仓库聚合、版本化管理。缺点是使用 AsciiDoc 而非 Markdown,如果你已经是 Markdown 生态(Docusaurus),切换成本较高。
- Backstage TechDocs:Spotify 开源的 Service Catalog + TechDocs 平台,适合大型组织需要 Service Registry 的场景。如果你只需要轻量文档站而不需要完整的 Service Catalog,Docusaurus 更简单直接。
作为架构 Leader 的落地建议#
如果你正在带领一个 Java/Spring Boot + Golang + K8s 团队尝试这套文档治理体系:
-
在服务脚手架中内置
/docs/模板:用 cookiecutter 或自定义 Maven archetype,直接内置/docs/目录结构 + ADRtemplate.md。让每个新服务开箱即用。 -
GitHub PR 模板增加 checklist:“更新了
docs/adrs/吗?index.md是否反映了变更?“让文档更新成为 PR 流程的一部分,而不是额外的负担。 -
Platform Team 提供统一规范:统一的
_category_.json和 Mermaid 样式规范,确保聚合后视觉一致。 -
高性能系统额外关注:Kafka 事件 schema 演进策略(向后兼容)、Redis key 命名空间隔离文档、OceanBase 索引/分区调优记录。
-
搜索与 AI:接入 Algolia DocSearch v4(Docusaurus 3.9+ 原生支持 AI Ask 功能,2025 年已成熟)。
-
版本化:Docusaurus 内置 versioning,可按 domain 或全局版本。
总结#
对采用 Domain-aligned multi-repo 的团队来说,“中央架构 Repo + 各服务 Repo 内 /docs/ 目录 + Docusaurus 统一站"是一条值得尝试的组合。至少在我的实践里,它有这些比较明确的好处:
- 文档与代码更贴近:至少更容易让文档跟随代码一起变更,减少“过时 wiki 页面”
- Service Owner 自治:每个团队只负责自己的
/docs/,不需要去维护中心化 wiki - 统一入口:Docusaurus 聚合所有文档,形成可搜索、可版本化的单一真相来源
- 减少手工复制成本:Git 驱动、PR review、CI 自动 build,把重复劳动压到更少
- 避免文档漂移:PR 模板强制检查 ADR 更新,文档变更是代码变更的一部分
对于采用 Domain-aligned multi-repo 架构的团队,文档站有机会逐渐变成一个相对稳定的架构入口——新成员 onboarding、跨团队协作、故障排查、架构 review,都能先从这里开始。