
最近被问到"你们项目应该用单体还是微服务"的次数太多了,每次都得从头解释一遍。这篇把核心问题说清楚,不整虚的。
先说个暴论:很多团队盲目上微服务,就是被大厂的光环晃了眼。阿里、腾讯这些大厂确实在用微服务,但那是人家的业务规模和团队规模决定的。你要是三五个人、刚起步的产品,非要拆成十几个服务,那不是给自己找不痛快吗?
微服务解决的是真实的问题,但同时也会带来新的问题。这篇不站队,把两种方案的优劣摆出来,再给一个简单的判断框架,帮你做决定。
单体就是一个应用。所有代码放在一个代码库里,打一次包、部署一次,通常连接一个数据库。
拿电商系统来说,单体架构下,用户登录、商品展示、购物车、支付全都塞在一个应用里。改个购物车的逻辑,得重新部署整个应用。
听起来挺 low 的,但简单本身就是优势。
微服务把应用拆成多个独立的小服务,每个服务做一件事,各自运行。服务之间通过网络通信,通常走 API 或者消息队列。
还是那个电商系统,可能拆成用户服务、商品服务、购物车服务、支付服务。每个服务可以有自己独立的数据库、独立的团队、独立的上线节奏。
| 因素 | 单体架构 | 微服务架构 |
|---|---|---|
| 上手难度 | 快,简单 | 慢,需要更多配置 |
| 部署方式 | 一次部署全部 | 各服务独立部署 |
| 扩展方式 | 整体扩展 | 只扩展繁忙的部分 |
| 调试难度 | 简单,一个地方看日志 | 困难,错误跨越多个服务 |
| 适合团队规模 | 小型到中型 | 多团队 |
| 运行成本 | 较低 | 较高(更多服务器、工具、监控) |
| 数据一致性 | 简单,一个数据库 | 困难,数据分散 |
单体往往是更好的选择,不只是"入门级"的选择。以下这些场景,它真的赢了。
团队规模小。如果只有一两个小组,微服务带来的复杂度会消耗大量精力。你花在网络调用、服务契约、部署流水线上的时间,比花在业务功能上的还多。
产品还在快速迭代。早期产品形态变化很大。如果过早拆服务,边界十有八九画不对。代码在文件夹之间挪容易,跨服务迁移就麻烦多了。
想要简单的调试体验。在单体里,一个 bug 只有一个堆栈跟踪、一份日志。微服务里,一个用户请求可能穿过五个服务。要定位问题,得上链路追踪工具,还得有经验。
预算紧张。每个服务都要主机、监控、告警。单体架构的资源消耗要少得多。
需要强数据一致性。银行转账、订单和支付的状态同步,这类场景用单数据库加本地事务处理简单得多。
这不只是理论。Shopify 跑着世界上规模最大的 Ruby on Rails 单体架构之一,内部拆成了清晰的模块。Stack Overflow 多年用单体架构扛住了海量流量。2023 年,Amazon Prime Video 的一个团队把监控工具从微服务合并回单体,基础设施成本据说降低了约 90%。
微服务值得折腾,得是单体的痛苦已经真实存在。看看下面这些信号。
诚实回答下面五个问题。
大部分回答"否"? 继续用单体。它会很好地服务你。
大部分回答"是"? 微服务可能有帮助。先把一个服务拆出来,选择痛点最高的那个。
答案五五开? 看下面的折中方案。
模块化单体是一个应用,但在内部组织成清晰的模块。每个模块管理自己的代码和数据,模块之间通过定义好的接口通信。部署还是一个包。
这样既保留了单体的大部分简单性,又获得了微服务的大部分清晰结构。如果将来某个模块真的需要独立出去服务化,拆分要容易得多,因为边界已经存在了。
对大多数正在成长的团队来说,这是最聪明的默认选项。
单体 vs 微服务这场争论,没有唯一的赢家。单体对小团队和早期产品更简单、更便宜、更快。微服务帮助大型组织在多团队共享系统时依然保持速度。
一个好用的原则是:先从简单的开始,把代码组织好,只在痛苦真实且清晰的时候再拆分。
单体架构是不是很差的设计?
不是。架构清晰的单体对很多公司来说都是稳健的选择,包括一些规模相当大的企业。
以后能从单体迁移到微服务吗?
可以。大多数成功的微服务系统最初都是单体起步的。模块化单体让这个过渡平滑很多。
微服务性能更快吗?
不一定。服务间的网络调用本身就会产生延迟。微服务的优势在于团队独立性和扩展灵活性,而不是绝对速度。