拆微服务拆出麻烦的团队,技术选型往往没大问题,问题出在边界那一刀切歪了。微服务拆分边界切错比不拆更贵——这话听着像泼冷水,但边界一歪,跨服务查询、分布式事务、发版顺序耦合这几样会轮着找上门,而且不是一次性买单,是每个月都在续费。单体再烂,改个功能本地跑一遍就完事;边界切错之后,改一个字段要翻三四个仓库,还得排队等别人一起发版。

微服务拆分边界切错比不拆更贵,贵在哪儿
贵在三块。一是沟通成本,原来一个组内喊一嗓子的事,现在要写接口文档、等对方排期;二是发布成本,A服务加个必填字段,B服务没跟上就直接报错;三是认知成本,新人接手先得画服务调用图,图画完人也差不多晕了。这些成本不会在监控大盘上冒红,所以最容易被忽略,等发现的时候架构已经铺开了,回头比往前还费劲。
还有一块更麻烦的,扯皮。两个服务共用一张表,出问题谁都不认,日志翻半天,最后发现是对方悄悄改了字段含义。这种事一多,团队对拆分的信心就没了,后面再推什么架构调整都难。
按技术分层拆,是最常见的一种错
Controller一个服务,Service一个服务,DAO再一个服务。看着层次分明,实际是把一次本地方法调用活生生拆成三次网络往返。业务一改动,三个仓库一起提交,漏一个就线上出问题。这种拆法唯一的好处是“看着像微服务”,坏处是把单体的耦合全保留下来,还额外附赠了网络延迟和失败重试。
判断标准很土但管用:如果一个服务单独部署出去没有任何业务价值,那它就不该是一个服务。技术分层是代码内部的整理手段,不是部署单元,这两件事混一起就容易出事。
数据归谁,比代码放哪更关键
经常见到服务拆得挺利索,结果B服务直接连A服务的库读表。这一下边界就形同虚设了——A想加个索引得先问B,A想改字段名得先让B改代码。真正的边界其实是数据所有权:这张表谁能写、谁能读,定清楚了,服务边界才立得住。
读不过来怎么办?要么同步一份到自己的库里,要么走接口去拿。慢一点,但改起来自由。这个取舍得提前想明白,别等库被三个人连着用,再回头收就要动数据了。
按团队拆,不如按变更节奏拆
康威定律被引用得太多,很多团队干脆把组织架构直接当服务清单。问题是组织架构会变,人一调动,服务边界跟着尴尬。更稳的一个参考维度是变更频率:经常一起改的东西放在一起,一年动不了两回的塞到旁边去。
促销逻辑和商品主数据就是典型例子,前者隔三差五就要动,后者几个月才碰一次。捆在一个服务里,每次发版都得战战兢兢地回归一遍本来不该动的东西,时间全耗在这。
防腐层是边界上的缓冲垫
两个服务之间那层接口转换代码,很多人嫌啰嗦,直接让上游透传下游的实体类。短期省事,长期是灾难:下游改个字段名,上游编译不过。防腐层的作用就是把这个变化挡在边界外面,字段映射、版本兼容、默认值兜底都在这层做。
写起来不难,一个转换类加一组DTO就够了,难的是坚持不偷懒。一旦有人图快直接引了对方的实体,这层就漏了,而且会越漏越多,最后干脆谁都不写了。
有些系统现在真不该拆
团队不到十个人,领域还没摸清楚,请求量也不高,这时候拆微服务基本等于把未来的复杂度提前预支,利息还不低。单体的模块化做到位,一样能撑很久,改起来未必更慢。
要不要拆,我一般看三条:有没有独立的扩缩容需求,有没有独立的上线节奏,团队扛不扛得住多一套运维体系。三条里占一条再谈拆,一条都不占就先忍着,把接口和模块理清楚比什么都强。
拆之前先把模块理清,成本差一个量级
单体的包结构如果还是按controller/service/dao平铺,那拆分基本只能按技术层来,因为业务边界在代码里根本看不见。先按业务能力分模块,模块之间只走接口、不互相碰对方的表,这一步做完,边界自然就露出来了。
到那时候再拆,动作会小很多,基本是把已有模块拎出去。反过来,代码还是一锅粥就急着上容器、上注册中心,最后拿到的是分布式的混乱,比原来的单体难维护得多,日志散在几个地方,排查问题得先猜是哪一层挂的。
真要动手之前,把这几条过一遍:核心表有没有唯一的主人;一个业务改动会碰几个仓库;发版需不需要跨团队排期;有没有人专职盯这套基础设施;出问题日志能不能串起来。哪一条答不上来就先别拆,把模块化补上再说。边界画对了是省事,画错了就是负债,利息按天算,赖不掉的。
【版权声明】:本站内容若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!