做了这么多年开发我踩过最深的坑就是为了微服务而微服务。2020年我第一次带团队做微服务拆分当时觉得不拆就不是现代架构结果拆完以后10个人的团队维护20个服务每次改需求要跨3-5个服务发版上线时间从原来的半天变成三天。那段时间我最大的感悟是微服务是要付出代价的。后来陆续做了几次拆分和合并慢慢总结出一套经验。今天聊聊我自己的判断方法和实操过程不是教科书那套是真正踩过坑之后沉淀下来的东西。一、什么时候该拆很多文章会告诉你代码量到多少行就该拆了但我觉得真正的判断标准不是行数而是协作成本。我一般看这几个信号部署频率明显下降。一个功能改完了因为和其他模块耦合在一起别人改的东西还没测完你的代码就上不了线。如果两周才能发一次版说明单体已经开始拖慢你了。代码冲突变多。每次合并都有人在同一个文件上打架尤其是那种我也不想改但没办法的冲突说明模块边界已经模糊了。故障面太大。用户模块的一个小bug导致整个服务不可用所有模块一起遭殃。这个最疼也最容易被忽视——因为大家习惯了重启大法。你可以看看自己的项目如果中了3条以上是可以认真考虑拆分了。但说实话如果团队只有三四个人拆了反而是负担运维成本会把你们压垮。小团队老老实实用单体模块化做好比什么都强。二、怎么拆我见过最蠢的拆分方式是按技术层拆——“把Controller单独拆出来”、“把Model独立成服务”这是纯属给自己加戏。正确的拆法是按业务能力。举个例子一个电商系统你应该先画清楚业务域用户域管注册登录权限商品域管库存和分类订单域管下单支付退款。每个域之间通过事件通信不直接调数据库。判断标准很简单一个域的数据改了其他域需不需要同步知道不需要那就是独立服务的候选。实际拆的时候别想着一步到位。我用的方法是绞杀者模式说白了就是先挑一个最容易独立的模块给它单独建个API层然后把调用方一个个迁过去最后把老代码删掉。一次只拆一个拆完一个验证一个验证通过再拆下一个。从哪个模块开始拆我建议按两个维度排序变化频率和资源消耗。变化多又吃资源的比如搜索推荐优先拆。变化多但消耗小的比如用户权限次优先。变化少消耗大的比如日志报表看情况。两头都低的最后再说。三、拆完以后什么最坑我踩过最大的坑是分布式事务。单体里一个数据库事务解决的问题拆成微服务后变成了分布式事务。你查一下Saga模式但说实话最好的办法不是用什么模式而是重新设计业务边界让事务落在一个服务内部。如果实在避免不了那优先用最终一致性别强求强一致。第二个坑是调用链太长。A调BB调CC调D。链越长任何一个环节出问题都会被放大。我的经验是调用链深度控制在3层以内超过3层的用异步消息替代。第三个坑也是最常见的——服务拆了数据库没拆。所有服务还在读写同一个库你拆了个寂寞。每个服务必须有自己的数据库或者自己的schema服务间数据交换只走API不走数据库。四、总结一下我的经验拆到什么程度算合适我给自己定了一个标准一次需求变更需要修改的服务数不超过2个。如果超过了说明拆太细了合并回去。微服务架构的成熟度不是看你拆了多少个服务而是看你能不能独立部署、独立测试、独立扩容任何一个服务而对业务没有重大影响。最后说一句如果现在让我重来我会先花一两个月把单体内部的模块边界理清楚再考虑拆的事。模块化做好的单体比拆得稀碎的微服务好用十倍。这篇文章写到这我自己的博客aigcharness.com上还有一些具体的架构选型和工程实践文章有兴趣可以看看都是真实项目里沉淀下来的东西。