【文字稿】第13篇 微服务爆炸——从8个到60+个
愚人小屋
2026年05月16日 21:30
收录于文集
共26篇

《唯物开发辩证法》——用一家虚拟公司的十二年技术演进,穿透技术表面,理解决策背后的因果关系。本文是系列第16篇(第三阶段第5篇)。


第一段:场景还原

2020年,星衡莜选的服务数量从8个爆炸到60+个。

这是怎么发生的?2017年老徐明确拒绝了60个服务("运维复杂度爆炸"),只拆了8个。但2018-2020年间,服务数量仍然失控了。推动力来自两个方向:

第一,老张(架构师)的"过度设计"倾向。他在每个服务内部推动"进一步解耦"——交易服务拆成了下单服务、购物车服务、价格服务、优惠券服务、库存扣减服务、订单状态服务。他的理由是"每个子服务只做一件事,符合单一职责原则"。老徐当时忙于业务增长,没有干预。

第二,新入职的工程师推动"微服务化"。2018-2019年星衡莜选大量招聘,新工程师来自大厂,带着"微服务是最佳实践"的信念。他们推动将用户服务拆成登录服务、注册服务、用户信息服务、用户等级服务、用户标签服务。理由是"解耦后可以独立部署"——但用户等级服务的QPS只有0.1,独立部署的收益为零。

老徐后来复盘时说:"我犯了两个错误。第一,我以为'8个服务'的决策会一直被遵守——但组织大了,决策需要持续维护。我当时觉得8个服务的共识足够强,团队都理解为什么是8个而不是60个,没想到需要制度化的审批机制来守护这个共识。第二,我没有建立'服务拆分的审批机制'——任何人想拆服务,只需要团队内部决定。没有门槛,拆分就会失控。我当时忙于业务增长,把架构治理交给了老张——但老张自己就是拆分的推动者,他怎么可能阻止拆分?"

这两个错误的因果链条值得深挖。第一个错误——"共识足够强"的幻觉——根源在于老徐低估了组织规模对共识的稀释效应。2017年团队500人,老徐可以直接和每个技术骨干沟通,共识通过面对面交流建立。2020年团队2000人,新入职的工程师占一半以上——他们从未参与过2017年的"8个服务"决策讨论,只带着"微服务是最佳实践"的外部经验加入。共识不是被推翻的——是被稀释的。每进一个新人,共识就稀释一点。当新人占比超过50%时,旧共识已经不存在了。

第二个错误——"没有审批机制"——根源在于老徐把架构治理视为"技术决策"而非"制度设计"。2017年拒绝60个服务时,老徐做的是一个"技术判断"——判断60个服务的运维复杂度不可接受。但他没有把这个判断转化为"制度"——一个不依赖具体人的审批流程。当他自己忙于业务增长、把架构治理委托给老张时,制度真空就暴露了。老张作为架构师,他的职责是"设计最优架构"而非"守护架构边界"——这两个目标在微服务拆分上是矛盾的。设计最优架构倾向于"更细粒度的解耦",守护架构边界倾向于"阻止不必要的拆分"。让同一个人承担两个矛盾的目标,结果必然是其中一个目标被牺牲。

每个子服务都有自己的数据库、自己的RPC接口、自己的监控告警。服务数量从8个增长到60+个。

运维团队崩溃了。运维负责人找到老张:"60+个服务,每个服务2台ECS(主备),120台ECS。每台ECS需要监控CPU、内存、磁盘、网络。每天告警200条——大部分是'CPU使用率超过80%',但查了之后发现是正常的业务峰值。告警太多等于没有告警。"

更严重的是,一半的微服务QPS不到100。用户等级服务——日请求量不到1万次,QPS约0.1。但它占用了一台独立的ECS(2核4G,月费200元),一个独立的数据库(RDS,月费300元)。月费500元×12个月=6000元/年。60+个服务中,30个是这种"低QPS服务"——年浪费18万。

老徐把老张叫来:"微服务太多了。我们得合并。你推动的拆分,现在你来推动合并。"


第二段:需求解剖

用户的需要:系统稳定。用户不关心"微服务数量",用户关心"系统能不能用"。60+个服务,服务之间RPC调用链路复杂——一个下单请求经过10个服务。任何一个服务挂了,下单就失败。

业务的需要:降低运维成本。120台ECS的运维成本——人力(运维团队120人中的15人负责微服务运维,年薪30万×15=450万)+ 硬件(120台ECS,月费约5万,年费60万)= 510万/年。如果合并低QPS服务,可以减少ECS数量,降低运维成本。

技术的需要:降低系统复杂度。60+个服务的RPC调用链路——一个下单请求经过下单服务→购物车服务→价格服务→优惠券服务→库存扣减服务→订单状态服务→支付服务→通知服务。8次RPC调用,总延迟约8ms。如果其中任何一个服务超时,下单失败。调试困难——一个Bug需要追踪8个服务的日志。

付费意愿解剖:运维成本510万/年。合并低QPS服务可以减少30台ECS——节省约15万/年硬件成本+减少运维人力投入。但合并的代价——开发时间2个月(老张+2个后端开发,人力成本约10万)。ROI:15万/年 vs 10万一次性——1年回本。


第三段:验证设计

老张设计了一个合并方案验证:

合并原则:按QPS和业务相关性合并。QPS<100的服务合并到相关的高QPS服务。例如,用户等级服务(QPS 0.1)合并到用户服务(QPS 1000)。优惠券服务(QPS 50)和积分服务(QPS 30)和会员服务(QPS 20)合并为"权益服务"。

验证方法:先合并"用户等级服务→用户服务"作为试点。用户等级服务逻辑简单——根据用户消费金额计算等级。合并到用户服务后,用户服务增加一个"查询用户等级"的接口。

验证结果:合并后,用户等级查询的延迟从2ms(RPC调用)降到0.01ms(本地调用)。用户服务增加了一个接口,代码量增加200行——可接受。


第四段:判断逻辑

判断:必须合并低QPS服务。60+个服务中,30个是低QPS服务——QPS<100,占用独立ECS和数据库,运维成本高。合并后服务数量从60+降到25个。

但判断的约束条件:合并不能影响高QPS服务的独立部署。交易服务(QPS 5000)必须保持独立——因为它的写入量大,需要独立扩展。搜索服务(QPS 3000)必须保持独立——因为它的负载特征不同(读多写少)。

老徐的决策:合理归并。低QPS服务合并,高QPS服务保持独立。服务数量从60+降到25个。


第五段:架构取舍

业务架构:不变。

应用架构:服务数量从60+降到25个。合并方案——用户等级+用户标签→用户服务。优惠券+积分+会员→权益服务。下单+购物车→交易服务(保留独立)。价格服务保留独立(价格计算逻辑复杂)。库存扣减服务保留独立(写入量大)。

数据架构:合并后的服务共享数据库。用户服务和用户等级服务合并后,共享用户数据库——不需要RPC调用,本地查询即可。

技术架构:不变。Dubbo + Zookeeper + MySQL + Redis。ECS数量从120台降到80台。


第六段:实现穿透

【可视化】

技术解剖:服务粒度的辩证法——不是"越小越好",是"按团队边界和业务特征拆分"。

微服务的驱动力:团队并行开发。一个服务由一个团队负责——团队可以独立开发、独立部署。服务粒度应该匹配团队边界——一个团队负责一个服务。

微服务的代价:运维复杂度。每个服务需要独立的ECS、数据库、监控、告警。服务越多,运维成本越高。RPC调用延迟——本地调用0.01ms,RPC调用1ms。服务越多,RPC调用链路越长,总延迟越高。

为什么RPC比本地调用慢100倍?——底层原理。 一次RPC调用的完整链路:①序列化——将Java对象转换为二进制流(Hessian2协议,约0.1ms);②网络传输——TCP发送+接收(同机房约0.3ms);③反序列化——将二进制流还原为Java对象(约0.1ms);④服务端线程调度——从Netty的I/O线程切换到业务线程池(约0.1ms);⑤业务逻辑执行;⑥响应沿原路返回(序列化+网络+反序列化,约0.5ms)。总计约1.1ms。而本地方法调用只有JVM的栈帧操作——约0.01ms。差距100倍。当一次请求需要8跳RPC时,仅RPC开销就达8ms——加上业务逻辑,用户感知延迟超过200ms。这就是为什么60+个服务、8跳RPC链在用户体验上不可接受:RPC的序列化-网络-反序列化链路是固定成本,每增加一跳就累加一次。

服务粒度的辩证法:不是"越小越好",是"按团队边界和业务特征拆分"。团队边界——一个团队负责一个服务,服务粒度=团队粒度。业务特征——高QPS服务独立部署(需要独立扩展),低QPS服务合并(不需要独立扩展)。

为什么60+个服务是"过度拆分"? 因为拆分粒度小于团队粒度——一个团队负责多个服务。交易团队负责6个服务——下单、购物车、价格、优惠券、库存扣减、订单状态。6个服务之间的RPC调用是"团队内部调用"——不需要RPC,本地调用即可。过度拆分增加了运维复杂度,没有增加团队并行能力。

劳动对象:服务之间的RPC调用→本地调用。合并后,原来的RPC调用变成本地调用——延迟从1ms降到0.01ms。

劳动资料:Dubbo RPC→本地方法调用。

劳动者:25个服务团队,每个团队约56人(业务线开发约1400人÷25)。加上平台团队(中台、基础设施、DBA、运维、数据、安全)约600人,技术团队总计2000人。2000人技术团队的构成:开发约1400人(其中6条业务线约900人、中台10人、基础设施/平台工具约200人、数据团队约100人、搜索/推荐团队约100人、其他约90人),测试约180人,运维约120人,产品/设计约200人,管理约100人。

否定之否定:合理归并是对微服务爆炸的扬弃。保留了微服务的合理内核(团队自主权——每个团队仍然拥有自己的服务),抛弃了微服务的不合理内核(过度拆分——低QPS服务合并),增加了微服务没有的新能力(按业务特征差异化拆分——高QPS独立,低QPS合并)。这不是"回到单体",是在更高层次上的"按业务特征差异化拆分"。


第七段:数据反馈

合理归并后数据:服务数量从60+降到25个。ECS数量从120台降到80台——年节省20万。RPC调用链路从8次降到4次——下单延迟从8ms降到4ms。告警数量从200条/天降到50条/天。

但数据也暴露了新问题:合并后的服务代码量增大——用户服务从5万行增长到8万行。团队内部需要更好的代码组织——模块化、分层。


第八段:矛盾转化

合理归并解决了"微服务爆炸"的矛盾,但创造了"服务内部复杂度"的矛盾。这是否定之否定的常态——每一次"回到原点"都是在更高层次上。合理归并后的架构,既不是单体(服务之间有明确的边界和接口),也不是极端微服务(不会为了拆分而拆分)。


第九段:消亡分析

合理归并后的25个服务架构没有"消亡"。它持续运行,支撑了星衡莜选的业务。但它的边界会继续调整——当新的业务线加入时,可能需要拆分新的服务。当某些服务的QPS下降时,可能需要合并。架构不是静止的——它随历史条件变化而演进。


第十段:能力沉淀

【金句】

心法(判断力):服务粒度的标准不是"越小越好",是"按团队边界和业务特征拆分"。一个团队负责一个服务——服务粒度=团队粒度。高QPS服务独立部署,低QPS服务合并。拆分不是目的,是手段——手段服务于目的(团队并行开发)。当拆分不再服务于目的时(过度拆分增加了运维复杂度,没有增加团队并行能力),就该合并了。

内功(分析框架):服务粒度的决策框架——①这个服务的QPS是多少?(高QPS独立,低QPS合并)②这个服务由一个团队负责吗?(如果是,独立。如果多个服务由同一个团队负责,合并)③这个服务的业务特征和其他服务相似吗?(相似则合并,不相似则独立)④合并后代码量是否可接受?(<10万行可接受,>10万行考虑拆分)

招式(操作方法):合理归并的实施步骤——①统计每个服务的QPS和代码量,②识别低QPS服务(QPS<100),③按业务相关性合并(优惠券+积分+会员→权益服务),④先试点(用户等级→用户服务),⑤全量合并。

AI时代心法:AI可以帮你统计服务QPS、分析代码量、生成合并方案。但AI不能帮你判断"该不该合并"——因为这个判断依赖于"团队的边界"(一个团队负责几个服务),依赖于"业务的特征"(哪些服务是相关的),依赖于"合并后的代码量是否可接受"。粒度判断力是AI无法替代的。


历史注脚:本篇的技术决策参考了行业微服务过度拆分反思。星衡莜选是虚构的,但决策背后的历史逻辑是真实的。详见 ../../制作要求/参考资料.md 第八节。