Software Architect · 模块 11

单体不等于混乱,微服务也不等于架构。真正重要的是 boundary、ownership 和运维成熟度。

Modular monolith · service boundaries · operational complexity

§ 01

微服务用分布式复杂度的代价,买来独立性。如果你不需要这份独立性,这笔代价就白付了。

service 是一个组织单元

当一个团队有自己的活儿、节奏和职责时,一间独立的办公室才有帮助。如果大家反正都在同一个会议里,墙没什么用。

当一个 context 有自己的生命周期、owning team、负载画像、安全要求或发布节奏时,一个微服务才站得住脚。仅仅把代码挪进一个独立的可部署单元,是不够的。

modular monolith(模块化单体) 在早期往往更好:一个代码库、一次部署,但内部模块严格、有 public interface、没有循环依赖、ownership 清晰。

分布式会加上一份运维代价

一间厨房可能很挤。十间厨房则需要物流、沟通、配送时刻表,以及交接菜品的规则。

微服务需要 service discovery、observability、网络安全、向后兼容的 contract、distributed tracing、部署编排、事故响应、数据 ownership,以及 SRE 实践。只要有理由,这些都不是缺点。这是代价。

架构师必须诚实地问:拆分之后,哪种痛消失了,又冒出了哪种新的痛?

§ 02

好的拆分减少协调。坏的拆分,制造出比拆之前更多的审批会议。

例子:把 billing 抽出来

收银台、会计室和仓库彼此相连,但会计有自己的规则、审计和责任。

billing 有自己的合规要求、audit trail、与 payment provider 的集成,以及一个 owning team。它可以被抽成一个带自己数据和 contract 的 service:invoice、subscription、payment event。

这种拆分说得通:它保护了一个"出错代价高、变化节奏又不同"的领域。

反例:一张表一个微服务

如果仓库的每个货架都变成一家独立的店,顾客为了一个订单就得穿过十个收银台。

团队造了 users-serviceprofiles-serviceaddresses-serviceroles-service,但每个 use case 都要调用这四个。数据仍然耦合,发布仍然要协调,延迟和调试还都更糟了。

这就是 distributed monolith(分布式单体):有 service,却没有独立性。

自检
  • 哪个团队会拥有这个 service? - 这个 service 能不能独立发布? - 它拥有谁的数据? - 拆分之后,会冒出哪些新的 运维职责?