一个家族刚开始在一个四合院里住得好好的。人少,事少,一锅饭大家吃,一本账大家记。后来孩子成了家,各自有了各自的营生,人越来越多,院子还是那个院子。公共厨房排不开,谁要做点什么都不方便。不是谁跟谁处不来------是院子装不下了。分家,是被撑出来的。
软件系统也一样。**微服务不是谁坐在桌前设计出来的,是单体系统膨胀到一定程度,被从内部撑裂出来的。**每一条裂缝,都被一个微服务堵上。但裂缝堵上的同时,新的暗面代价就开始累积。这是我想说的事。
一个院子
最早的应用,大多是一个单体。订单、用户、支付、库存,全塞在一个进程里,共用一个数据库,共用一套部署。代码在一个仓库里,发布是一起发的。
好处很明显。调用就是函数调用,不会失败。数据要一致,一个事务就解决。出问题,翻一个仓库的日志就够了。简单,直接,好懂。系统小的时候,这个形态几乎挑不出毛病。
撑裂
但系统会膨胀。代码量涨,功能蔓延,数据量涨。一开始还能加机器扛,后来发现加机器也不顶用了。
改一处代码,怕动全身,谁都不敢随便碰。一个团队改完了想发布,另一个团队还在改另一个功能,发布卡在等。单库数据量撑到一定程度,慢查询拖垮整个库,所有模块一起遭殃。**这些痛不是谁造成的,是体量撑出来的。**院子就这么大,人再多就住不下。
分家
撑不住了就分家。订单拆出去,用户拆出去,各自立门户。每个服务有自己的代码、自己的数据库、自己的部署节奏。互相之间不靠函数调用了,改用 REST API 或 gRPC 通信------通过网络发请求。REST 是 HTTP 接口,人看得懂,调试方便。gRPC 更快更省,适合服务之间高频调用。
**分家的好处是实的。**订单服务要扩容,只扩订单,不用拖上全系统。支付团队改代码发版,不卡用户团队。每个服务独立演进,互不阻塞。裂缝被堵上了。

暗面
但分家不是免费的。单体的问题是明面的:编译慢、发布卡、资源挤------看得见,摸得着,动手就知道往哪使劲。微服务的问题,是暗面的。

一个请求原来是一个函数调用,现在要穿五六个服务。链路断了,挂在哪了?不翻分布式追踪根本看不出来。原来数据一致性靠数据库事务,一个库兜底。现在数据散在多个库里,谁也不替谁兜。要保证一致,得自己搞分布式事务,或者退一步用最终一致性。两条路都有代价。
原来运维一个进程。现在要监控十几个服务的健康、链路、日志,工具链全要重搭。原来函数调用不会失败。现在网络调用会超时、会失败、会重试,每个调用都要考虑容错。原来改一个字段改一处。现在改一个接口字段,上下游所有服务都要跟着改、跟着发。
每个拆分单看都合理,拆完才发现住进了难十倍的房子。
怎么判断
所以微服务到底要不要上?**我的看法是:别问该不该上,问撑住了没有。**单体还撑得住的时候,拆就是给自己找事。一个十几人的团队、一个跑得动的单库,硬拆成微服务,大概率是用十倍的复杂度,换一个还没出现的问题。
我见过拆早了的团队。系统没那么大,硬拆成二十几个服务,调试一个问题要跨四五个服务看日志,排期比单体还慢。也见过该拆没拆的,单库撑到几百亿行,一个慢查询全站宕机,最后不得不连夜拆。
判断的线不复杂:代码量、功能耦合、数据量、团队规模,这几个维度撑到单体扛不住了,拆。没撑住,就别拆。**微服务不是更高级的架构,是撑不住之后的妥协。**每一个解决方案在消除一个问题时,都在引入新的负担。权衡这事,审慎一点,不亏。