上周跟杭州做精品生鲜电商的老周吃饭,他刚从公司熬完大促的压测,坐下来灌了半杯冰美式,脸都是垮的。说去年Q3脑子抽了,把跑了三年的单体系统拆成17个微服务,这次618压测,一个库存服务的数据库连接池打满,整个调用链路卡得死死的,用户下单页转三圈都刷不出来,最后紧急回滚到原来的单体备份,才把压测拉回正轨。真的惨。
不是所有系统都配拆微服务
整个研发团队满打满算8个人,原来的单体代码仓库拉下来,本地配个依赖半小时就能跑起来,改个商品上下架的逻辑,不用跟任何人同步,提个测就能上线,每月迭代四五个版本都顺得很。结果去年年初看了几篇大厂的技术分享,觉得“微服务是先进架构,不拆就是技术债”,咬咬牙花了三个月拆服务,还特意买了商用的服务注册中心,搭了全套监控。哦对了,他们当时拆服务的时候,还特意把原来的单体数据库拆成了五个独立的库,美其名曰数据隔离,结果跨库关联查询的时候,慢到要死。

拆完头俩月确实爽,发版不用停整个系统,改哪个服务就发哪个,看起来很光鲜。但很快不对了。你总共就8个开发,拆出来17个服务,平均一个人要管俩还多,出了问题连哪个服务的负责人是谁都要翻群聊记录。说句不好听的,这就是典型的拿大厂的药方给自己吃,吃出急性肠胃炎。微服务从一开始就不是为了“显得技术先进”做的,它解决的是“团队规模到几十上百人,单体代码库改不动,上线互相踩脚,不同业务线迭代节奏不一样”的问题。你三五个人的小团队,代码都在一个仓库里,改个东西不用跨部门排期,拆什么拆?拆完了你要维护注册中心,要处理服务间超时重试的熔断逻辑,要搞定跨服务的数据一致性,这些杂事够你多招两个运维的。
拆完之后藏在暗处的成本
拆完第三个月,问题就开始扎堆冒。最头疼的是数据对不上。用户付了钱,订单服务记了已支付,库存服务因为网络波动没扣减库存,两边的数据差了快三百单,每天要花两个运维人工导表对账,对到眼睛都花。还有原来改个商品详情的字段,只需要改单体里的一个接口,现在要同步改商品服务、搜索服务、推荐服务三个地方,稍微漏一个,线上搜索就出乱子。上次他们搞会员积分升级,原来单体的话半天就能上线,结果拆完之后要协调用户、积分、支付、营销四个模块的负责人排期,前后折腾了两周,上线当天还出了积分重复发放的问题,赔了快三万的优惠券。没人想得到。真的。

很多人算拆微服务的账,只算开发拆代码的时间,不算后面的隐性成本。比如你要搭全链路追踪的工具,要写大量的降级兜底逻辑,要给每个服务配独立的日志采集,还要定期处理服务间的版本兼容问题。这些事,小团队做下来,至少要占掉三分之一的研发精力,本来能用来做业务功能的时间,全花在维护架构上了。
真要落地得先攥住几个底线
我跟老周聊到最后,给他捋了几个实在的原则,都是这几年见过上百个团队踩坑踩出来的。最核心的原则是,拆服务的边界要跟着团队的组织边界走,不是按业务功能硬拆。比如你团队已经分成了独立的订单组、库存组、用户组,每个组自己对业务结果负责,那拆成对应的服务才顺。要是所有服务都归同一个开发小组管,拆了就是纯给自己找事,最后还要跨服务调接口改代码,比单体还麻烦。还有一条硬线,服务数量千万别超过团队人数的1.5倍,比如你有10个开发,最多拆15个服务,不然光排障都排不过来。另外,别上来就搞什么高大上的服务网格,那玩意儿是给几百人的大团队用的,小团队搞个简单的注册中心加结构化日志采集就够用了,搞太复杂纯属浪费精力。
老周听完当天就回去提了方案,打算把现在的17个服务合并到7个,先把不必要的复杂度砍了再说。说实话,架构从来没有绝对的先进落后一说,适合自己团队的,能少加班少出bug的,就是好架构。别看着别人拆微服务拆得爽,就跟着瞎凑数,最后把自己坑得天天救火,真的不值当,对吧?