TL;DR

本文核心观点:

  1. 模块边界优于微服务 — “You don’t need microservices. You need better module boundaries.” 微服务不是技术解决方案,而是组织结构的映射。
  2. 两个披萨规则说的是团队规模 — 关键是团队内部的协调成本,不是代码部署形式。亚马逊和 Netflix 的成功有赖于 500+ 工程师和专属工具团队。
  3. 微服务的隐藏成本在本地开发、调试、测试、API 变更四处 — 分布式追踪、契约测试、多服务协调是单体里不存在的负担。
  4. 模块化单体是被遗忘的第三条路 — 如果前四个拆分信号都不满足,先做好模块化单体——边界清晰,拆分成本最低。

那个激进的宣言

Reddit 上最近有一篇文章的标题很吸睛:

“Microservices: Shackles on your feet”

副标题更激进:

“You don’t need microservices. You need better module boundaries. Split only when teams are truly independent, scaling needs are night-and-day different, or your headcount is pushing 150+. Before any of that — fix the code, draw real boundaries inside the monolith, set up tracing. Microservices don’t fix a messy codebase. They just spread it across the network and make it someone else’s 3 AM problem.”

你不需要微服务。你需要更好的模块边界。

这篇文章引发了激烈讨论,因为它挑战了微服务作为”现代架构”的默认地位。


亚马逊与 Netflix:神话拆解

微服务架构的流行通常归功于亚马逊和 Netflix 的成功案例。

故事是这样的:

  • 亚马逊从单体架构开始
  • 随着规模增长,单体成为瓶颈
  • 他们拆分成微服务
  • 成功!

但这个故事漏掉了关键细节。

亚马逊的真实情况

亚马逊在 2000 年代初期确实经历了架构转型,但:

  1. 他们当时有 500+ 工程师
  2. 每个团队负责一个独立业务领域
  3. 部署频率是每天数千次
  4. 他们有专门的工具团队支持微服务生态

“Microservices are Amazon’s solution to the problems that come with its organizational structure, a team has to be fed with two pizzas.. They are not a technical solution.”

微服务是亚马逊解决其组织结构问题的方案(一个团队只能吃两个披萨),不是技术解决方案。

亚马逊的真实情况

Netflix 的情况

Netflix 的微服务转型:

  • 发生在拥有数百名工程师之后
  • 需要自建一整套基础设施(服务发现、熔断、监控)
  • 成本:数百万美元的工程投入

两个披萨规则的真正含义

亚马逊 CTO Werner Vogels 提出的”两个披萨规则”经常被误读。

原意:团队规模应该小到两个披萨就能喂饱(6-10 人),这样沟通效率最高。

误读:所以每个团队应该有自己的微服务。

逻辑错误

两个披萨规则说的是团队规模,不是服务边界

一个 10 人的团队可以维护:

  • 一个单体应用
  • 10 个微服务
  • 或任何介于两者之间的架构

关键是团队内部的协调成本,不是代码部署形式。

💡 Key Insight

两个披萨规则说的是团队规模,不是服务边界。关键是团队内部的协调成本,不是代码部署形式。


微服务的隐藏成本

微服务架构有隐藏的成本,往往在决定采用后才显现出来。

开发成本

方面 单体 微服务
本地开发 python app.py 启动 10 个服务,配置端口,处理依赖
调试 单步调试 分布式追踪,日志聚合
测试 单元 + 集成测试 契约测试,集成测试,端到端测试
API 变更 修改函数签名 版本管理,向后兼容,协调多个团队

运维成本

每个服务需要:

  • 独立的 CI/CD pipeline
  • 独立的监控和告警
  • 独立的日志聚合
  • 独立的服务发现配置

故障排查成本

💡 Key Insight

微服务把单体的”跨函数调用”变成了”跨网络调用”——延迟、可靠性、版本兼容问题全部从代码层面暴露出来,这不是改进,是把问题复杂化。

单体中的 bug:

  1. 查看堆栈跟踪
  2. 定位代码行
  3. 修复

微服务中的 bug:

  1. 查看入口服务日志
  2. 发现它调用了服务 A
  3. 查看服务 A 的日志
  4. 发现它调用了服务 B
  5. 查看服务 B 的日志…
  6. 20 分钟后发现是网络超时
  7. 检查服务发现配置
  8. 发现问题在服务 C 的依赖版本

💡 Key Insight

微服务中的 bug 需要查看入口服务日志、逐层追踪调用链,20 分钟后才发现是网络超时——这才是分布式系统的真正代价。

故障排查成本

一位 Reddit 用户的经历:

“I was working in a place that had a monolithic web app in C# (around 2015). Not really a problem… New CTO comes in and mandates that we switch to a microservice architecture… Split the monolith up into like 5 microservices… It quite literally killed the product. We basically rewrote the whole thing for no gain, more work, and made it harder to make changes.”


何时拆分,何时坚守

✅ 应该考虑拆分的信号

信号 说明
团队规模 > 150 人 康威定律开始严重阻碍开发
完全不同的扩展需求 一个服务需要 100 实例,另一个需要 2 个
真正的团队独立性 团队可以独立发布,不需要协调
技术栈分歧 必须用不同的语言/框架
合规要求 某些数据必须隔离处理

❌ 不应该拆分的理由

坏理由 为什么错
“微服务很酷” 技术选择应该基于需求,不是流行趋势
“我们将来会需要” YAGNI(You Aren’t Gonna Need It)
“单体代码太乱” 微服务会把混乱分散到网络上
“每个领域一个服务” 领域边界 ≠ 服务边界
“为了容错” 单体也可以有多个实例

模块化单体:被遗忘的第三条路

在单体和微服务之间,有一个被忽视的选择:模块化单体(Modular Monolith)。

核心思想

保持单一部署单元,但在代码层面严格划分模块:

核心思想

💡 Key Insight

模块化单体不是”妥协”,而是大多数中小团队的最佳选择——在需要时,边界已经清晰,拆分成本最低。

模块边界规则

  1. 模块间通过 API 通信
  2. 禁止跨模块数据库访问
  3. 每个模块有自己的业务逻辑

    模块化单体的优势

优势 说明
开发简单 单一仓库,单一部署
重构容易 IDE 支持,类型检查
测试简单 集成测试在一个进程内
性能更好 没有网络调用开销
未来可拆分 当真正需要时,边界已经清晰

模块化单体的优势

真实案例:Shopify

Shopify 是一个成功的模块化单体案例:

  • 支持数百万商家
  • 单一 Rails 代码库
  • 清晰的模块边界
  • 在需要的地方(支付、图片处理)使用独立服务

Strangler Fig:渐进式演进

如果你已经有一个单体,想要迁移,永远不要重写

使用 Strangler Fig 模式(绞杀榕模式):

原理

  1. 在单体前放置一个代理层(API Gateway)
  2. 新功能在新服务中实现
  3. 逐步将旧功能从单体中移出
  4. 最终,单体被”绞杀”,可以退役

示例

Strangler Fig Pattern - 渐进式演进

为什么不要重写

“When you do split, use a strangler fig. Not a rewrite. Never a rewrite.”

重写的风险:

  • 业务逻辑遗漏
  • 需要同时维护两套系统
  • 迁移期间的混乱
  • 可能不会成功(著名的 Netscape 重写灾难)

结尾:没有银弹

微服务不是银弹。单体也不是。

正确的架构是适合你的团队规模和业务需求的架构。

决策 checklist:

  • 你的团队有 150+ 人吗?
  • 你有真正的团队独立性需求吗?
  • 不同组件有完全不同的扩展需求吗?
  • 你有资源维护微服务基础设施吗?
  • 单体内部已经有清晰的模块边界吗?

如果前四个都是”否”,而最后一个是”否”——先做好模块化单体

💡 Key Insight

如果前四个都是”否”,而最后一个是”否”——先做好模块化单体。

正如 Reddit 上的共识:

“As most wise developers have said ‘it depends’”

正如大多数聪明的开发者所说:”看情况。”

不要盲目追随亚马逊或 Netflix 的架构。他们解决的问题可能不是你面临的问题。

从简单开始,在需要时演进。


参考与延伸阅读


深度阅读时间:约 8 分钟

本文灵感源自 2026-03-16 Reddit r/programming 讨论。

发布于 aazh2026.github.io