项目从1个模块拆成8个微服务,然后我又合了回去

📅 发布时间:2026/7/5 2:56:52 👁️ 浏览次数:
项目从1个模块拆成8个微服务,然后我又合了回去
摘要我们项目从 1 个 SpringBoot 单体拆成了 8 个微服务用了半年。然后在接下来的一年里分布式事务、调试地狱、运维成本翻倍团队被折磨得够呛。最后我做了一个决定合回去。不是退回到大泥球而是用模块化单体的方式重新组织代码。这篇文章复盘了整个过程——当初为什么拆、踩了什么坑、为什么合、合回去之后怎么做的。事情的开始我们为什么要拆2023 年底我加入了一个做 SaaS 的项目。那时候项目还小一个 SpringBoot 应用跑得好好的用户量 5 万出头QPS 不到 200。有一天老板说“我们要拆微服务。”我当时第一反应是好呀拆了更专业大家都在拆微服务不拆就落伍了。拆的理由听起来也挺合理的用户量在涨马上到 10 万了以后肯定要扩团队从 3 个人扩到了 8 个一个代码仓库 merge 经常冲突路演模块的慢查询偶尔拖慢整个应用如果能独立部署就好了现在回头看这三个理由里只有第二个勉强站得住脚。用户量 10 万是什么概念一个单体扛百万 DAU 都没问题。至于慢查询——加个索引的事非要动架构。但我们当时就是拆了。大家都觉得微服务是现代软件的标配不拆显得不够架构师。2026 年的面试风向已经变了。gankinterview.cn 的一篇文章提到面试官现在问的是你的业务量级真的需要微服务吗而不是你用过微服务吗1。可惜两年前没人这么问我。拆分过程8 个微服务是怎么诞生的我们照着 DDD 画了一圈领域边界最后定了 8 个服务投资者服务 (investor-service) 路演服务 (roadshow-service) 企业服务 (company-service) 互动服务 (interaction-service) 通知服务 (notification-service) 数据服务 (data-service) 资料服务 (material-service) 网关服务 (gateway-service)边界画得挺清晰的。每个服务有自己的数据库用 Feign 做 RPC 调用Nacos 做注册中心和配置中心Sentinel 做限流熔断SkyWalking 做链路追踪。技术栈选得中规中矩没什么花活spring:cloud:nacos:discovery:server-addr:nacos:8848sentinel:transport:dashboard:sentinel:8080拆的过程大概花了三个月。改代码、配 CI/CD、写 Dockerfile、调 K8s 部署加班是常态但大家干劲十足——毕竟在做架构。上线那天8 个服务在 K8s 里整整齐齐跑起来Grafana 面板上每一个 Pod 的绿色指示灯看着确实爽。蜜月期之后问题一个接一个爽了大概两个月。分布式事务的噩梦第一个大坑是分布式事务。上市公司预约路演的流程原来是一个 Service 方法里搞定校验企业信息 → 创建路演场次 → 开通互动提问 → 发通知。数据库事务一包要么全成、要么全滚。拆了之后变成roadshow-service → company-service校验企业→ interaction-service开通互动→ notification-service发通知。四个服务四个数据库跨服务调一个 RPC 就断一个数据库连接。Spring 的Transactional彻底废了。我们试过 Seata 的 AT 模式GlobalTransactionalpublicRoadshowcreateRoadshow(RoadshowDTOdto){companyClient.verifyCompany(dto.getCompanyId());interactionClient.enableQA(dto.getRoadshowId());roadshowRepo.save(roadshow);notificationClient.send(路演预约成功);}看上去挺优雅的。但问题出在异常场景——互动服务超时了Seata 回滚了路演创建和企业校验但通知那边已经发出了路演预约成功的短信。用户收到通知去页面一看路演不存在。这就是最终一致性问题。SAGA 也好TCC 也好本质上都是把保证不出错变成了出错后想办法弥补。对电商这种场景来说补偿逻辑写起来非常痛苦。后来我读到 Matthias Patzak 的观点“短期内模块化单体在开发速度和重构灵活性上具有压倒性优势。”1这话一点不夸张。一个 Bug 需要起 4 个服务才能调有一次线上报了一个 Bug投资者打开互动提问提问提交成功了但路演页面显示未开通互动。排查过程是这样的看 roadshow-service 日志 → 调用 interaction-service 返回了超时看 interaction-service 日志 → 开通互动成功回写状态时调 roadshow-service 超时看网络 → 两个服务之间间歇性丢包开发环境复现启动 gateway、roadshow-service、interaction-service、company-service 四个服务 Nacos MySQL Redis。本地 16G 内存跑不满。整个过程花了将近两天真正修代码只用了半小时。剩下的时间全在搭环境和追调用链。运维成本翻了三倍CI/CD 从 1 条流水线变成 8 条。每次升级依赖包要改 8 个 pom.xml。日志分散在 8 个地方查一个问题要拼多个 ELK 查询。gankinterview.cn 提供了一个量化对比1百万级用户系统模块化单体每月基础设施成本约 3000 美元微服务架构约 12000 美元——差 4 倍。我们没到那个量级但运维人力成本是实打实的。原来一个后端运维就能搞定的事拆完之后所有开发都要学 K8s、学链路追踪、学怎么排查分布式问题。团队只有 8 个人实在不划算。网络延迟和雪崩原来一个方法调用是纳秒级。变成 RPC 后是毫秒级。不只是延迟。有一次>为什么决定合回去2024 年底我做了一个决定合回去。不是拍脑袋。看下面的表格维度拆分前单体拆分后8 微服务部署时间5 分钟30 分钟编排依赖新增一个跨模块功能1-2 天1 周左右线上问题平均排查时间30 分钟2-4 小时运维人力0.5 人1.5 人CI/CD 流水线维护1 条8 条生产事故半年2 次5 次数据摆在这儿没什么好解释的。核心问题是我们团队 8 个人业务耦合度高没有任何一个模块需要独立扩缩容。拆分带来的收益独立部署、技术栈自由我们一个都没享受到付出的代价倒是全吃了。2026 年 51CTO 将模块化单体列为年度架构趋势指出微服务架构的过度拆分问题被广泛反思2。这件事早两年就该反思了。合回去之后模块化单体怎么做合回去不是把代码全倒回一个大 jar 包了事。那是退回到大泥球不是解决问题。我们做的事情是用 Maven 多模块保持边界platform/ ├── platform-investor ├── platform-roadshow ├── platform-company ├── platform-interaction ├── platform-notification ├── platform-common └── platform-start (启动模块)每个模块有自己的package和internal子包。internal下的类不对外暴露。模块之间通过public接口调用编译期就能检查出越界引用。这一步还借助了 ArchUnit 做架构测试ArchTestvoidmodules_should_not_depend_on_internal_packages(){noClasses().that().resideOutsideOfPackage(com.platform.roadshow..).should().dependOnClassesThat().resideInAnyPackage(com.platform.roadshow.internal..).check(classes);}CI 里跑不通过就不让合并。事务回归简单原来跨模块调用就是一个方法调用不需要 RPC不需要分布式事务。Spring 的Transactional又好使了。如果将来真的要拆边界已经画好了。哪天路演模块真的需要独立部署团队变大、独立发布节奏只需要把platform-roadshow抽出来加一层 RPC 适配层就行。边界不需要重画。什么时候该拆什么时候不该拆经过这一圈折腾我自己的判断标准是这样该拆的情况团队超过 50 人多个小组并行开发不同业务域不同模块有完全不同的发布节奏比如核心业务两周一发、后台管理一天一发某个模块需要独立扩缩容路演服务 QPS 1000数据服务 QPS 5技术栈确实需要异构比如算法服务用 Python业务用 Java不该拆的情况团队不到 20 人沟通成本本来就低业务强耦合跨模块事务多没有独立扩缩容需求整体 QPS 不超过 1000运维能力跟不上团队没有专门的 DevOpsMartin Fowler 说的好“除非系统复杂到无法作为单体管理否则不要考虑微服务。”1我以前觉得这是保守。现在觉得这是常识。总结一句话模块化单体是小团队的甜点区。微服务不是目的是好架构的结果。架构的选择不是哪种更高级而是哪种更适合你现在的阶段。我们当时的问题不是单体不好是代码写得烂。代码写得烂拆成微服务只会变得更烂——只不过烂得更有层次感了。如果再来一次我会先把单体内部的模块边界理清楚做好高内聚低耦合。等有一天业务规模真的到了单体扛不住的时候再拆也不迟。参考作者唐悦玮 公众号同名从后端出发用 AI 拓展到全栈的工程师。“微服务已死2026 面试官开始推崇模块化单体”: gankinterview.cn ↩︎ ↩︎ ↩︎ ↩︎“2026 技术架构新趋势从微服务回潮到 AI 原生架构”: 51cto.com ↩︎