微服务
解释微服务以业务边界和独立部署为核心的架构取舍,以及它为什么会把本地调用、单库事务和单进程观测转化为分布式系统问题。
[!info] related notes
- 所属 MOC:Backend Architecture MOC、Distributed Systems MOC
- 边界设计:Bounded Context、分层架构
- 协作:事件驱动架构、API Gateway
- 一致性:分布式事务
微服务
[!abstract] 一句话定义 微服务把围绕业务能力的模块提升为可独立部署、扩缩和演进的服务边界,并通过网络契约协作。它的价值来自独立性和故障隔离,代价是把本地调用、事务和调试变成分布式系统问题。
它真正解决什么
适合解决:
- 不同业务能力需要独立发布;
- 团队可围绕服务自治;
- 某些模块需要独立扩缩或故障隔离;
- 技术/合规/数据边界确实不同;
- 单体发布和协作已成为稳定瓶颈。
“代码很多”或“想用 Kubernetes”本身不是拆分理由。
服务边界围绕什么
优先围绕:
- 业务能力和统一语言;
- 业务不变量;
- 数据写入所有权;
- 变化率和发布节奏;
- 团队责任;
- 故障与容量边界。
不是按 Controller、Service、Repository 技术层拆成“用户 Controller 服务”“用户数据库服务”。
数据所有权
常见原则是服务拥有自己的写模型,其他服务通过 API / Event 协作,而不是直接改它的表。
[!warning] “每个服务一台数据库”不是定义 可以共享同一物理数据库实例,但 Schema、写权限和迁移责任应有边界;反之,即使每个服务单独数据库,若业务边界混乱也不是真正自治。
同步与异步通信
同步 API
Service A → HTTP / gRPC → Service B
适合立即需要结果的查询和命令。代价:时间耦合、级联延迟、Timeout / Retry 和部分失败。
异步 Event / Message
Service A commits local state
→ publishes Event
→ B / C process independently
适合解耦、削峰和多个下游。代价:最终一致、重复、顺序、Schema Evolution 和观测复杂度。
同一系统通常混合使用两者。
一条同步调用链为什么危险
Gateway → Order → Inventory → Payment → Promotion → User
每增加一个同步依赖,整体成功率和尾延迟都会受最慢/最不可靠节点影响。需要:
- Deadline Propagation;
- Bulkhead / Circuit Breaker;
- 幂等;
- 降低跨服务 Chatty Calls;
- 必要时改为异步流程。
跨服务事务
本地 ACID 事务不能直接覆盖多个服务。常见策略:
- 重构边界,让不变量回到同一服务;
- Saga / Compensation;
- Transactional Outbox / CDC;
- Idempotent Consumer;
- 极少数受控场景使用 2PC / TCC。
详见 分布式事务。
必要基础设施
微服务通常要求成熟的:
- Service Discovery / Load Balancing;
- API Gateway / Auth;
- 配置与 Secret;
- Distributed Tracing / Logs / Metrics;
- Message Broker;
- Contract / Integration Test;
- CI/CD、Canary、Rollback;
- Runtime Ownership 和 On-call。
这些是成本,不是架构图上的装饰。
Modular Monolith 为什么常是更好起点
one deployment
+ clear modules
+ explicit interfaces
+ owned data boundaries
它保留本地事务和简单运维,同时训练真正模块边界。只有当独立部署/扩缩/团队自治收益持续超过分布式成本时,再把模块提升为服务。
模块化单体与微服务
| 维度 | 模块化单体 | 微服务 |
|---|---|---|
| 部署 | 一个单元 | 多个独立单元 |
| 调用 | 进程内接口 | 网络 API / Event |
| 事务 | 本地事务容易 | 跨服务需额外策略 |
| 运维 | 较简单 | 服务、网络和数据治理复杂 |
| 故障隔离 | 进程级较弱 | 可按服务隔离,但需正确治理 |
| 团队自治 | 依赖代码边界 | 可独立发布和拥有 Runtime |
什么时候不该拆
- 团队很小、产品仍快速试错;
- 模块边界和业务语言尚不稳定;
- 没有统一观测、发布和 On-call;
- 主要问题其实是慢查询、糟糕依赖或单体模块混乱;
- 需要频繁跨服务事务才能完成基本用例。
观测和治理
至少关注:
per-service SLO and ownership
cross-service trace and dependency map
API / Event contract version
retry and circuit-breaker behavior
queue lag / DLQ
schema migration compatibility
release / rollback / incident blast radius
面试表达
微服务不是把代码拆小,而是把稳定的业务边界提升成独立部署和数据所有权边界。它能带来团队自治、独立扩缩和故障隔离,但会引入网络不确定、跨服务事务、可观测性和运维成本。因此我通常先做模块化单体,只有独立部署或容量边界的收益明确时才拆服务。