从微服务到模块化单体:架构师的两难抉择

举报
PikeTalk 发表于 2025/12/23 11:29:36 2025/12/23
【摘要】 我还记得那个决定“上微服务”的会议。那是2016年。康威定律(Conway’s Law)被奉为圣经,Netflix 是我们的北极星。每场技术大会都在承诺:微服务能解决我们的扩展难题、团队协作问题和部署瓶颈。“我们会拥有自治团队,”我们说,“独立部署、技术自由、真正的可扩展性。”我们深信不疑。于是,我们把单体应用拆成了47个服务。三年后,我们花在排查分布式链路追踪上的时间,比写新功能还多。“独...

我还记得那个决定“上微服务”的会议。

那是2016年。康威定律(Conway’s Law)被奉为圣经,Netflix 是我们的北极星。每场技术大会都在承诺:微服务能解决我们的扩展难题、团队协作问题和部署瓶颈。

“我们会拥有自治团队,”我们说,“独立部署、技术自由、真正的可扩展性。”

我们深信不疑。于是,我们把单体应用拆成了47个服务。

三年后,我们花在排查分布式链路追踪上的时间,比写新功能还多。“独立”的服务通过共享数据库和同步调用紧紧耦合在一起。每次部署都要协调五个团队。可观测性(observability)的账单眼看就要突破六位数。

我们只是用一套更昂贵的问题,换掉了原来那套。

如今,七年过去了,我看到了一个趋势:那些当初一窝蜂上微服务的团队,正在回撤——不是回到老式的“意大利面式”单体,而是转向一种更理性的架构:模块化单体(Modular Monolith)

这并不是倒退,而是一种进化。


我们曾经相信的承诺

先说清楚一点:微服务本身没有错。它要解决的问题是真实存在的。

2010年代初,单体应用确实碰到了天花板:上百人的团队互相踩脚、部署排队长达数天、一个团队的bug能让整个系统崩溃、想单独扩展认证服务却不得不把整个单体一起扩容……

微服务描绘了一幅美好蓝图:

独立扩展 —— 只扩真正需要的部分
团队自治 —— 端到端负责自己的服务
技术灵活 —— 为不同任务选合适的工具
故障隔离 —— 一个服务挂了,其他还能跑
快速部署 —— 各自发布,高频交付

对亚马逊、Netflix、Uber 这样的巨头来说,这套方案确实奏效。他们有规模、有工程成熟度、有基础设施投入,也有匹配的组织结构。

但我们忽略了一个关键点:他们的规模不是我们的规模,他们的问题也不是我们的问题。

可我们还是照搬了他们的解决方案。


我们后来面对的现实

大约在微服务落地18个月后,问题开始浮现。

复杂性税(The Complexity Tax)

从前我们只监控一个应用,现在要管47个服务。每个服务都有自己的:

  • 部署流水线
  • 数据库(或者共用数据库,那就违背初衷了)
  • 日志配置
  • 指标看板
  • 健康检查
  • 熔断器
  • 重试策略
  • 超时设置

运维开销爆炸式增长。我们不得不引入:

  • 服务网格(我们选了 Istio,结果它自己成了新难题)
  • 分布式追踪(先用 Jaeger,后来换成 Datadog)
  • 集中日志(ELK → Splunk)
  • API 网关
  • 服务发现
  • 配置管理
  • 密钥管理

我们只是把应用复杂度换成了基础设施复杂度——而后者更难理解和调试。

分布式调试噩梦

有用户反馈结账失败。简单吧?查日志就行。

但这次请求穿过了12个服务:

API网关 → 认证服务 → 用户服务 → 购物车服务 → 库存服务 → 定价服务 → 优惠服务 → 支付服务 → 订单服务 → 通知服务 → 分析服务 → 物流服务

到底哪里出错了?是超时?网络分区?数据库死锁?还是接口契约变了?

过去看个堆栈就能定位的问题,现在变成了一场“考古挖掘”。

逃不掉的耦合

我们按“限界上下文”设计服务,读过《领域驱动设计》,画过漂亮的架构图。

但现实很骨感。

支付服务需要用户数据,订单服务依赖库存,通知服务几乎要所有信息。

于是我们建起了同步调用。服务网格缓解了一些问题,但没解决根本:运行时依赖让服务逻辑上依然紧耦合

定价服务一挂,结账就失败;库存服务变慢,首页也卡顿;认证服务一重启,30多个服务就得处理瞬时故障。

我们实现了物理分离,却没能摆脱逻辑耦合。

团队碎片化

康威定律是把双刃剑。

我们按服务划分团队:购物车团队管购物车服务,订单团队管订单服务。

但业务功能呢?它们横跨多个服务。

“加个礼品包装选项”要协调四个团队;“上线会员积分”涉及九个服务。简单功能变成了跨团队项目,充满依赖、会议和集成测试噩梦。

我们为了服务自治,牺牲了功能交付速度。


行业的集体反思

我们不是孤例。2019–2020 年左右,风向开始转变。

亚马逊 Prime Video:回归单体

2023年,Prime Video 工程团队发表案例:他们把音视频监控服务从微服务改回单体,成本直降90%

原来的微服务架构包括:

  • 用 AWS Step Functions 编排分布式组件
  • 服务间通过 S3 传递数据
  • 网络开销大
  • 状态管理昂贵

合并成单进程后,他们:

  • 消除了网络跳转
  • 去掉了序列化开销
  • 简化了可观测性
  • 改用垂直扩展而非水平扩展

网上炸锅了:“亚马逊放弃微服务了!”

不,他们只是为具体问题选择了合适的架构

Shopify:回归“模块化单体”

Shopify 在2022年的博客中坦言:他们拆过分服务,遇到类似问题,最终又合并回所谓的“模块化单体”。

关键洞察:“我们承受了微服务的复杂性,却没享受到它的好处。”

他们的服务其实是:

  • 一起部署(共享发布周期)
  • 通过直接调用耦合
  • 规模小到不需要独立扩展

于是他们合并了代码,但保留了内部模块边界:清晰的接口、合理的数据库隔离。

Uber:混合路线

Uber 从未全盘微服务化。他们采取混合策略:

  • 核心服务(调度、定价、支付)保持独立——这些确实需要独立扩展
  • 小功能服务合并成“领域单体”
  • 即使在大服务内部,也通过明确接口维持模块化

教训是:架构不是非黑即白,而是因地制宜


什么是模块化单体?

先澄清概念:模块化单体 ≠ 老式“意大利面”单体。

老式单体:

  • 依赖混乱
  • 全局共享状态
  • 难以理解
  • 部署风险高
  • 边界模糊

模块化单体:

  • 单一部署单元
  • 模块边界清晰
  • 模块间通过定义好的接口通信
  • 理论上可拆出独立服务
  • 共享进程,但逻辑隔离

打个比方:

  • 微服务 = 一片独栋住宅区

    • 每栋房子独立
    • 自己维护水电
    • 基础设施开销大
    • 通信靠“马路”(网络)
    • 适合需求差异大的场景
  • 模块化单体 = 一栋公寓楼

    • 共享水电管道
    • 户与户有墙隔离
    • 成本低、管理简单
    • 通信靠“门”(函数调用)
    • 适合需求相似的场景

如果你住公寓就够用,何必非买独栋?


架构师的决策框架

那么,到底该怎么选?这是我现在的判断标准。

什么时候适合微服务?

  1. 真有扩展需求
    系统每秒处理百万级请求,且不同模块的负载差异巨大。
    (不是“将来可能要扩展”,而是现在就有明确瓶颈

  2. 团队规模大
    50+工程师在同一领域工作,共享代码库导致严重协作冲突。
    (不是“想要自治”,而是已有组织痛点

  3. 技术栈确实不同
    某部分必须用 Python(比如机器学习),另一部分必须用 Go(高性能 API)。
    (不是“想试试 Rust”,而是有真实技术需求

  4. 业务域真正独立
    支付系统和库存系统互不影响,一个挂了不会拖垮另一个。
    (现实中很少见——大多数业务比我们想象的更紧密)

  5. DevOps 成熟
    你有:

    • 每个服务的 CI/CD
    • 完整的可观测体系
    • 能处理分布式调试的 on-call 团队
    • 熟悉分布式系统的工程师
      如果连基础监控都搞不定,加30个服务只会雪上加霜。

什么时候适合模块化单体?

  1. 早期阶段 / MVP
    产品还在验证市场,业务边界模糊,可能三个月就大改方向。
    → 先做简单架构,等需求稳定再拆。

  2. 中小团队(5–20人)
    团队能高效协作,理解整个代码库。
    → 分布式系统的开销远大于自治收益。

  3. 读多写少的系统
    大部分是查询操作,靠缓存和数据库副本就能扩展。
    → 计算层无需独立伸缩。

  4. 业务逻辑高度交织
    订单依赖库存,库存依赖定价,定价又依赖用户……
    → 强行拆分会制造更多耦合。

  5. 成本敏感
    运行40个服务的成本远高于4个:

    • 每个服务都要计算资源(常被过度分配)
    • 负载均衡器
    • 日志监控
    • 运维人力
      → 合并能显著降本。

如何从微服务迁回模块化单体?

如果你已在微服务泥潭中挣扎,这里是一条务实路径:

第一步:识别服务集群

画出你的服务拓扑图:

  • 哪些服务总是一起部署?
  • 哪些重度共享数据?
  • 哪些流量低到不值得独立部署?
    → 这些就是合并候选。

第二步:从低风险服务开始

别第一天就把支付和认证合并!
先从内部工具、边缘功能入手,控制爆炸半径。

第三步:保持模块边界

合并不等于乱炖。即使在一个代码库里,也要:

  • 用不同包/命名空间隔离
  • 定义清晰接口
  • 禁止直接访问其他模块数据库(走服务层)
  • 明确模块负责人
    → 目标:未来仍可按需拆出。

第四步:全面度量

跟踪关键指标:

  • 部署频率(应提升)
  • 故障排查时间(应缩短)
  • 开发效率(应感觉更快)
  • 运维成本(应下降)
    → 如果没改善,说明方法错了。

第五步:持续迭代

这不是一次性工程。也许你把10个服务合并成3个模块化单体,同时保留5个真正独立的服务。
没有“最多服务”或“最少服务”的奖杯,只有“有效解决问题”的胜利。


真实的权衡

坦白说,两种架构各有得失:

微服务的优势:
✓ 真正独立扩展
✓ 技术栈灵活(当真需要时)
✓ 故障隔离(若设计得当)
✓ 团队自治(需成熟组织支撑)

微服务的代价:
✗ 运维复杂度高
✗ 分布式调试困难
✗ 网络延迟
✗ 数据一致性挑战
✗ 基础设施成本高

模块化单体的优势:
✓ 运维简单
✓ 调试容易
✓ 成本低
✓ 开发效率通常更高
✓ 模块间支持原子事务

模块化单体的代价:
✗ 需要纪律维持边界
✗ 部署是“全有或全无”(可用功能开关缓解)
✗ 垂直扩展有上限(但通常比你想的高)
✗ 共享故障域

没有绝对优劣,只有是否适合当下。


架构成熟度模型

15年经验告诉我:架构随组织成熟度演进

  • 阶段1:小团队(5–15人)
    → 单体(最好从第一天就模块化)
    → 简单基础设施
    → 快速迭代,清晰归属

  • 阶段2:成长团队(15–50人)
    → 模块化单体 + 1–2个独立服务(如文件存储、AI模型)
    → 加强自动化测试和部署

  • 阶段3:大团队(50–200人)
    → 模块化单体 + 微服务混合
    → 仅在真正需要独立性的领域拆分
    → 建立 DevOps 文化和平台团队

  • 阶段4:超大组织(200+人)
    → 以微服务为主,但严格治理
    → 平台工程成为核心能力
    → 但仍会在合适场景用模块化单体

你不能跳过阶段。10人创业公司搞微服务,只是在 cosplay Netflix。


如果重来一次,我会怎么做?

如果能回到2016年,我会:

1. 从模块化开始

第一天就构建有清晰边界的单体:

  • 按领域分包
  • 模块间接口明确
  • 数据库逻辑隔离(即使共用实例)
  • 用 CI 检查禁止跨模块违规依赖
    → 这样未来才有选择权。

2. 战略性拆分

不是“全部拆”,而是:“这个模块确实有不同扩展/技术/团队需求。”
一次拆一个,测量效果,再决定下一步。

3. 打好基础

无论单体还是微服务,都必须有:

  • 完善的测试(单元、集成、端到端)
  • 自动化部署
  • 可观测性(日志、指标、链路)
  • 功能开关(安全发布)
    → 这些比服务数量重要得多。

4. 为变化而设计

别只为今天的组织或规模优化。
要设计成:接口清晰、耦合低、内聚高、易测试
→ 这些原则超越架构风格。


架构师的真正职责

残酷的真相是:

你的工作不是选微服务还是单体,而是理解上下文并做出明智权衡。

每个架构决策都有代价。你的任务是:

  • 明确你真正要解决的问题
  • 了解你的约束条件(团队、预算、时间、规模)
  • 诚实评估选项(而非追逐潮流)
  • 做出适合当前情境的决定
  • 规划演进路径(因为情境会变)

最好的架构师,不是画出最漂亮架构图的人,而是帮团队可持续交付价值的人


如何判断架构是否成功?

别数服务数量。看这些:

✅ 开发者能独立交付功能
(不是“理论上能”,而是实际上能

✅ 调试问题在合理时间内完成
(出事了能快速定位修复)

✅ 新人能快速上手
(系统可理解、文档齐全、边界清晰)

✅ 成本与业务价值匹配
(没在基础设施上花冤枉钱)

✅ 团队不被运维压垮
(on-call 可控、部署顺畅、监控有用)

✅ 能持续演进而非推倒重来
(架构支持变化,而非阻碍它)

如果你满足这些,你的架构就是成功的——不管叫微服务、单体还是混合体。


钟摆还会再摆回来

我预测:

行业会过度纠正,大量团队因微服务之苦而回归单体。博客会宣称“微服务是个错误”。

然后,5–7年后,当这些单体再次膨胀、团队继续扩张,大家又会重新发现服务拆分的价值。钟摆将再次摆向微服务。

这很正常。技术趋势本就会震荡。每次摆动都让我们学到新东西。

真正的教训不是“微服务坏”或“单体好”,而是:上下文比教条更重要。


我对初级架构师的建议

当有人问我“该不该用微服务?”,我会反问:

“你具体想解决什么问题?”

不是“哪种架构酷?”
不是“Netflix 用什么?”

而是:你现在面临什么可衡量的具体问题,微服务能解决它吗?

如果答案是“以后可能要扩展”或“我们想要团队自治”(但你们只有8个人),那答案就是

如果答案是“我们每秒处理1000万请求,数据库扛不住了”或“80人团队部署要三天”,那或许可以考虑。

从简单开始,有目的地演进,解决真实问题,而非假设问题。


我们真正需要的架构

这些年我明白了一件事:

最好的架构,不是最复杂的,而是:

  • 解决你真实的问题
  • 匹配你团队的能力
  • 支撑你业务的需求
  • 能随情境变化而演进
  • 不天天跟你作对

有时候是微服务,有时候是模块化单体,很多时候是混合体。

简单不是耻辱,复杂也没有奖赏。

作为架构师,你的目标不是建造最炫酷的系统,而是打造最有效的系统

而有时候,“有效”恰恰意味着选择那个平淡、简单、聚合的方案

那不是 vision 的失败,而是智慧的体现

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。