Files
test-repo/docs/zh-cn/appendix/6-architecture-and-system-design/monolith-to-microservices.md
T
sanbuphy ef70b1d8e1 feat: add comprehensive backend topics and fix build issues
## 新增内容

### 附录文档扩展
- 扩展前端项目架构文档 (frontend-project-architecture.md)
- 扩展后端项目架构文档 (backend-project-architecture.md)
- 扩展数据治理文档 (data-governance.md)
- 扩展数据可视化文档 (data-visualization.md)
- 扩展分布式系统文档 (distributed-systems.md)
- 扩展高可用文档 (high-availability.md)
- 扩展单体到微服务文档 (monolith-to-microservices.md)
- 扩展系统设计方法论文档 (system-design-methodology.md)
- 扩展 Docker 容器文档 (docker-containers.md)
- 扩展 Kubernetes 文档 (kubernetes.md)
- 扩展 Linux 基础文档 (linux-basics.md)
- 扩展神经网络文档 (neural-networks.md)

### 新增交互式组件
- 数据治理组件: DataQualityDemo, DataGovernanceFrameworkDemo, DataLineageDemo
- 数据可视化组件: ChartTypeSelectorDemo, DashboardLayoutDemo
- 分布式系统组件: CAPTheoremDemo, ConsistencyModelsDemo, DistributedChallengesDemo
- 高可用组件: AvailabilityCalculatorDemo, FailoverStrategyDemo
- 系统设计组件: SystemDesignStepsDemo, CapacityEstimationDemo
- Docker 容器组件: DockerArchitectureDemo, DockerLifecycleDemo
- Kubernetes 组件: K8sArchitectureDemo, K8sWorkloadsDemo
- Linux 基础组件: LinuxFileSystemDemo, LinuxCommandDemo, LinuxPermissionsDemo
- 神经网络组件: NeuronDemo, NetworkLayersDemo, NetworkArchitectureDemo
- 单体到微服务组件: ArchEvolutionDemo
- 项目架构组件: ProjectArchitectureComparisonDemo
- 附录导航组件: AppendixFlowMap

### 英文版重构
- 将 en-us 目录重命名为 en
- 更新相关配置和组件中的语言代码

## Bug 修复
- 修复 index.js 中重复的组件导入语句导致的 build 失败
- 恢复被注释的 InvertedIndexDemo 和 SearchRelevanceDemo 导入
- 修复 HomeFeatures.vue 中 en-us 与 config.mjs 中 en 不一致导致的语言切换问题

## 其他改进
- 添加构建脚本 (scripts/build.mjs)
- 更新依赖版本
2026-02-26 04:35:28 +08:00

157 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 从单体到微服务的演进
::: tip 前言
**没有哪个架构是"最好的",只有"最适合当前阶段的"。** 从单体到微服务不是一步到位的跳跃,而是随着业务规模和团队规模增长,逐步演进的过程。过早拆分微服务和过晚拆分一样危险。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **演进路径**:理解从单体到微服务的四个阶段
- **拆分时机**:知道什么时候该拆、什么时候不该拆
- **拆分策略**:掌握按业务域拆分的方法论
- **通信模式**:了解服务间同步和异步通信的选择
- **数据拆分**:理解数据库拆分的挑战和方案
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 架构演进路径 | 单体→模块化→SOA→微服务 |
| **第 2 章** | 拆分时机与原则 | Conway 定律、团队自治 |
| **第 3 章** | 拆分策略 | DDD 限界上下文、绞杀者模式 |
| **第 4 章** | 服务通信 | REST、gRPC、消息队列 |
| **第 5 章** | 数据拆分 | 数据库拆分、数据同步 |
---
## 1. 架构演进路径
架构演进不是技术驱动的,而是**组织规模驱动的**。当团队从 5 人增长到 500 人时,单体架构的协作效率会急剧下降。
| 阶段 | 架构 | 团队规模 | 特点 |
|------|------|---------|------|
| 起步期 | 单体应用 | 1~10 人 | 所有代码在一个项目中,部署简单 |
| 成长期 | 模块化单体 | 10~50 人 | 代码按模块划分,但仍然一起部署 |
| 扩张期 | SOA(面向服务) | 50~200 人 | 按业务线拆分为粗粒度服务 |
| 规模期 | 微服务 | 200+ 人 | 细粒度服务,每个团队独立开发部署 |
<ArchEvolutionDemo />
::: tip Conway 定律
"设计系统的组织,其产生的架构等同于组织的沟通结构。"——Melvin Conway
简单说:3 个团队做一个系统,最终会变成 3 个服务。架构拆分的本质是**组织拆分**。
**反向 Conway 定律**:既然组织结构决定了系统架构,那么想要什么样的架构,就先调整成什么样的组织结构。比如你想拆出独立的支付服务,就先组建一个独立的支付团队。很多公司微服务拆分失败,不是技术问题,而是组织没有跟着调整。
:::
---
## 2. 什么时候该拆微服务?
不是所有系统都需要微服务。过早拆分会带来不必要的复杂性。
| 信号 | 说明 | 建议 |
|------|------|------|
| 部署冲突频繁 | 多个团队改同一个代码库,经常冲突 | 考虑拆分 |
| 某模块需要独立扩容 | 搜索模块需要 10 倍于其他模块的资源 | 考虑拆分 |
| 技术栈需要差异化 | AI 模块用 Python,主站用 Java | 考虑拆分 |
| 团队 < 10 人 | 沟通成本低,单体足够 | 不要拆 |
| 业务还在探索期 | 需求变化快,边界不清晰 | 不要拆 |
| 没有 DevOps 能力 | 没有 CI/CD、容器化、监控体系 | 不要拆 |
---
## 3. 拆分策略
### 3.1 按业务域拆分(DDD 限界上下文)
DDD(领域驱动设计)的限界上下文(Bounded Context)是拆分微服务的最佳指导原则。每个限界上下文对应一个独立的业务域,有自己的数据模型和业务规则。
**什么是限界上下文?** 同一个词在不同业务域中含义不同。比如"用户"在用户域是指注册信息(姓名、邮箱),在订单域是指下单人(收货地址、支付方式),在推荐域是指行为画像(浏览历史、偏好标签)。限界上下文就是划定一个边界,在这个边界内,术语和模型有明确统一的含义。
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 用户域 │ │ 订单域 │ │ 支付域 │
│ │ │ │ │ │
│ User │ │ Order │ │ Payment │
│ Profile │ │ OrderItem │ │ Refund │
│ Address │ │ Cart │ │ Transaction │
│ │ │ │ │ │
│ 用户服务 │ │ 订单服务 │ │ 支付服务 │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└────── API 调用 / 事件通信 ───────┘
```
| 限界上下文 | 核心实体 | 对应服务 |
|-----------|---------|---------|
| 用户域 | User、Profile、Address | 用户服务 |
| 商品域 | Product、Category、SKU | 商品服务 |
| 订单域 | Order、OrderItem | 订单服务 |
| 支付域 | Payment、Refund | 支付服务 |
| 物流域 | Shipment、Tracking | 物流服务 |
### 3.2 绞杀者模式(Strangler Fig Pattern
不要一次性重写整个单体,而是像绞杀榕一样,逐步用新服务替换旧模块:
1. 在单体外部创建新服务
2. 通过代理层将部分流量路由到新服务
3. 验证新服务稳定后,逐步迁移更多流量
4. 最终完全替换旧模块
---
## 4. 服务通信模式
| 方式 | 协议 | 特点 | 适用场景 |
|------|------|------|---------|
| REST | HTTP/JSON | 简单通用,生态好 | 对外 API、CRUD 操作 |
| gRPC | HTTP/2 + Protobuf | 高性能,强类型 | 内部服务间高频调用 |
| 消息队列 | AMQP/Kafka | 异步解耦,削峰填谷 | 事件通知、异步任务 |
| GraphQL | HTTP/JSON | 客户端按需查询 | BFF 层、移动端 |
::: tip 同步 vs 异步的选择
- **需要立即返回结果** → 同步(REST/gRPC
- **不需要立即返回** → 异步(消息队列)
- **一个事件触发多个动作** → 异步(发布-订阅)
经验法则:能异步就异步,同步调用链越长,系统越脆弱。
:::
---
## 5. 数据拆分:最难的部分
微服务拆分中最痛苦的不是代码拆分,而是数据库拆分。每个服务应该拥有自己的数据库,但这意味着跨服务查询变得困难。
| 挑战 | 描述 | 解决方案 |
|------|------|---------|
| 跨服务 JOIN | 不能直接 JOIN 两个服务的表 | API 组合查询、数据冗余 |
| 分布式事务 | 跨库事务无法用本地事务 | Saga、本地消息表 |
| 数据一致性 | 多个服务的数据可能暂时不一致 | 最终一致性、事件驱动 |
| 数据迁移 | 从共享库迁移到独立库 | 双写过渡、数据同步工具 |
---
## 总结
从单体到微服务是一个渐进的过程,不是一蹴而就的革命。
回顾本章的关键要点:
1. **演进路径**:单体→模块化单体→SOA→微服务,每一步都有明确的驱动力
2. **拆分时机**:团队规模、部署冲突、扩容需求是拆分的信号
3. **拆分策略**:用 DDD 限界上下文指导拆分,用绞杀者模式渐进迁移
4. **通信选择**:能异步就异步,同步调用链越短越好
5. **数据拆分**:最难但最重要,接受最终一致性是关键心态转变
## 延伸阅读
- [Building Microservices](https://www.oreilly.com/library/view/building-microservices-2nd/9781492034018/) - Sam Newman 微服务经典
- [Monolith to Microservices](https://www.oreilly.com/library/view/monolith-to-microservices/9781492047834/) - 渐进式迁移指南
- [Domain-Driven Design](https://www.domainlanguage.com/ddd/) - Eric Evans 的 DDD 经典
- [The Strangler Fig Pattern](https://martinfowler.com/bliki/StranglerFigApplication.html) - Martin Fowler 的绞杀者模式