"我们用户量涨了,要不要拆微服务?"——这是共享科技接到的最多的架构咨询之一。本文结合近三年服务京津冀中小企业的落地经验,把这笔账算清楚:什么阶段该拆,什么阶段拆了反而更慢、更贵。
很多团队的焦虑来自一句话:"大厂都在用微服务。"但大厂拆微服务的前提是组织和流量:几百个开发并行作业,单机部署早已撑不住峰值。而多数中小项目的现实是 2~5 个后端、日订单几千到几万,这套前提并不成立。选架构不是追新,而是匹配当前的团队规模、流量特征和运维能力。
一、微服务的三笔隐性成本
1. 运维账:复杂度不是减了,是换了地方
单体时代一个部署包、一份日志就能定位问题;拆成十几个服务后,链路追踪、集中日志、服务注册发现、灰度发布、配置中心全部成为必需品。我们见过一个日活不足一万的商城系统,拆完之后光基础设施的维护就占了小团队近一半的工时——原本写业务的精力,被吃进了"伺候架构"里。
2. 一致性账:本地事务变成了分布式难题
单体内一个 @Transactional 能解决的问题,跨服务后要靠消息最终一致、对账补偿、幂等设计来兜底。每一笔跨服务的数据变动,都是潜在的数据不一致事故点。对交易类系统来说,这笔账最重,也最容易在深夜告警里体现出来。
3. 团队账:康威定律绕不开
系统结构终将映射到团队结构。3 个后端维护 8 个服务,意味着每个人都要跨域补位,代码评审、联调、排障全部交叉,沟通成本不降反升。服务的粒度不该由技术潮流决定,而应由团队人数和业务边界决定。
| 维度 | 传统单体 | 模块化单体 | 微服务 |
|---|---|---|---|
| 上线速度 | 快 | 快 | 慢,依赖多 |
| 运维成本 | 低 | 低 | 高,基础设施成套 |
| 独立扩容 | 不支持 | 不支持 | 支持 |
| 故障隔离 | 差 | 差 | 好 |
| 适用团队 | 1~3 人 | 3~15 人 | 15 人以上、多团队 |
二、模块化单体:被低估的中间路线
1. 物理上是一个进程,逻辑上是清晰边界
模块化单体仍是单个应用、单个数据库,但代码内部按业务域切成订单、商品、用户、营销等模块,模块之间只通过接口调用,不共享内部实现。部署与开发体验和单体一样简单,而业务边界已经先理顺了——这是它最大的价值:今天把边界画清楚,明天才拆得动。
2. 拆分的三条纪律
模块化单体要长期成立,靠纪律而不是自觉:模块间只允许走接口,编译层面互相不可见;公共能力(登录、鉴权、通用工具)下沉到独立基础包;每个模块独立测试,保证"拆出去就能跑"。做到这三条,未来任何模块需要独立部署时,迁移成本都可控。
在工程落地上,我们通常按"目录即模块"的约定组织代码:每个业务模块自带自己的 controller、service 与数据访问层,模块目录之外不允许出现本模块的表名。再配合一条简单的静态检查脚本扫描跨模块引用,边界就能在代码评审之外多一道机器防线。这套做法改动很小,却让"边界腐化"这类最难察觉的问题在提交阶段就被拦下。
实战提示:最常见的不规范是模块间直接 SELECT 对方模块的数据表。跨模块访问数据必须走对方提供的接口,否则边界名存实亡,将来拆分时所有直查的 SQL 都要返工。
三、什么时候才值得拆微服务
满足以下条件越多,拆分的收益才越能覆盖成本:
- 流量差异大:某个模块峰值流量是其他模块的十倍以上,需要独立扩容节省成本;
- 多团队并行:两个以上小组在同一代码库里频繁互相阻塞,发布排期打架;
- 故障需要隔离:某模块频繁出问题拖垮整个系统,业务已无法承受全站抖动;
- 技术栈确有差异:个别模块对性能或语言有硬性要求,单体难以兼顾。
如果一条都不占,或者只占一条且不痛,结论通常是:先把模块化单体做扎实,把人力投在业务上。我们给社区团购客户做的供应链系统就是典型案例——日订单破万仍运行在模块化单体上,两年里零次因架构问题导致的停机,等业务真正长出独立扩容需求时,再按模块逐个迁出即可。
一句话总结:架构选型的第一问不是"哪个更先进",而是"哪个问题更真实"。微服务解决的是组织和规模问题,不是代码写多了的必然归宿。先把边界画清、纪律立住,拆分随时可做、也随时可等。
系统越做越大,越来越难改?
先做一次架构诊断,再决定要不要拆。





