单体应用 vs 微服务
单体还是微服务?这不是非此即彼的选择,而是演进过程中的阶段性决策。
1. 单体架构
所有功能模块打包为单个应用,共享代码库与数据库。
类型演进
简单单体 → 模块化单体 → 分布式单体(伪微服务)
↑ ↑ ↑
起步阶段 团队扩大 反模式
单体优势
| 优势 | 说明 |
|---|---|
| 开发简单 | 无需考虑分布式问题 |
| 易测试 | 集成测试在一个进程内完成 |
| 部署便捷 | 单个 artifact,一键部署 |
| 性能高效 | 本地调用无网络开销 |
| 事务简单 | 单数据库天然支持 ACID |
单体痛点
- 代码耦合严重,任何改动都需全量回归
- 技术栈锁死,难以渐进式引入新技术
- 部署粒度粗,小改动也需全量发布
- 团队并行开发困难,合并冲突频发
模块化单体
渐进式改良:在单体内部划分清晰模块,为未来拆分做准备。
// 通过包结构体现模块边界
com.example.order
├─ application
├─ domain
├─ infrastructure
└─ api
com.example.inventory
├─ application
├─ domain
├─ infrastructure
└─ api // 仅暴露接口,不依赖 order 内部
2. 微服务架构
将应用拆分为多个独立部署的服务,每个服务围绕业务能力构建。
微服务特征
| 特征 | 说明 |
|---|---|
| 单一职责 | 一个服务只负责一个业务领域 |
| 独立部署 | 服务可独立构建、测试、部署 |
| 去中心化治理 | 技术栈可多样,数据可自治 |
| 容错设计 | 单点故障不影响整体 |
| 基础设施自动化 | CI/CD、容器化、服务治理必备 |
拆分策略
┌──────────────────────────────────────────┐
│ 按业务能力拆分(推荐) │
│ Order Service | Inventory Service | ... │
├──────────────────────────────────────────┤
│ 按子域拆分(DDD) │
│ Core Domain | Supporting | Generic │
├──────────────────────────────────────────┤
│ 按团队边界拆分(康威定律) │
│ Team A → Service A | Team B → Service B │
├──────────────────────────────────────────┤
│ 按数据变更频率拆分 │
│ 高频数据独立服务 | 低频数据共享服务 │
└──────────────────────────────────────────┘
3. 康威定律
Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations.
—— Melvin Conway, 1968
系统设计受限于沟通结构。反过来说:想实现什么架构,先构建对应的组织。
逆康威定律
主动调整组织结构以匹配期望的架构:
期望架构 组织结构
───────── ─────────
Order Service ←→ Order Team
Payment Service ←→ Payment Team
User Service ←→ User Team
(微服务) (自治小队)
团队拓扑
| 团队类型 | 职责 | 示例 |
|---|---|---|
| 流对齐团队 | 端到端业务交付 | 订单团队 |
| 平台团队 | 内部平台服务 | DevOps 平台 |
| 复杂子系统团队 | 高复杂度组件 | 推荐引擎 |
| 赋能团队 | 专项能力提升 | 安全赋能 |
4. 演进路径
不要一次到位,遵循演进式拆分策略:
Step 1: 单体(启动验证)
↓ 业务验证成功,团队扩张
Step 2: 模块化单体(清晰边界)
↓ 某模块独立发布需求强烈
Step 3: 提取独立服务(逐个拆分)
↓ 持续演进
Step 4: 微服务集群(按需扩展)
绞杀者模式(Strangler Fig)
渐进替换遗留系统:
┌──────────────┐
│ 单体应用 │
└──────────────┘
↓
┌──────────────────────────┐
│ API Gateway │
│ ├─ /api/v2/orders → Order Service(新)
│ └─ /api/v1/* → 单体(遗留)
└──────────────────────────┘
5. 何时拆分微服务
| 信号 | 说明 |
|---|---|
| 部署频率过高冲突 | 多团队争抢部署窗口 |
| 代码变更冲突频发 | 并行开发困难 |
| 特定模块需独立扩容 | 热点模块资源浪费 |
| 技术栈锁死 | 无法引入新技术 |
| 故障隔离需求 | 局部故障影响全局 |
6. 微服务挑战
| 挑战 | 应对策略 |
|---|---|
| 分布式事务 | Saga 模式、TCC、消息最终一致性 |
| 服务发现 | Consul、Eureka、Nacos |
| 配置管理 | Config Center、环境变量 |
| 链路追踪 | OpenTelemetry、Jaeger |
| 监控告警 | Prometheus + Grafana |
| 故障隔离 | 熔断、降级、限流 |
总结
| 维度 | 单体 | 微服务 |
|---|---|---|
| 开发复杂度 | 低 | 高 |
| 部署频率 | 低 | 高 |
| 技术异构 | 难 | 易 |
| 故障隔离 | 差 | 好 |
| 数据一致性 | 强 | 最终一致 |
| 团队规模 | 小(<10人) | 大(多团队) |
| 基础设施要求 | 低 | 高(必须自动化) |
建议:系统早期从单体开始,业务发展后再渐进式拆分。微服务不是目标,而是解决组织与规模问题的手段。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。