资讯动态

我的后端技术栈演进之路:从单体到微服务的实战思考

发布时间:2026/9/8 3:09:30 来源:尧图企业网站定制
五年前我接手了一个日活刚破十万的电商系统——一个经典的Spring Boot单体应用。所有业务模块用户、商品、订单、库存、支付全被塞在同一个WAR包里。那时候开发确实爽新功能增删改查一气呵成一个本地事务搞定所有逻辑部署不过扔个JAR包的事。但用户量翻了几番之后这个“甜蜜的负担”开始变得沉重。每次发布都像在走钢丝改个文案要全量回归测试发布周期从一天拖到两周三十多号人挤在同一个代码库里代码冲突成了家常便饭更可怕的是一个同事用POI导Excel导致JVM内存溢出整个系统直接瘫痪。最惨的一次大促库存服务的一个小bug引发了订单系统雪崩。当“发布一次如临大敌”成为常态时我们决定拆。第一次拆分把单体拆成了“分布式大单体”微服务的理念很美好——按业务边界拆分每个服务独立部署、独立扩展。我们兴冲冲地把系统拆成了用户服务、订单服务、商品服务、库存服务。然而很快发现这些服务之间存在着千丝万缕的数据库调用和代码依赖。所谓的“服务”本质上只是把原来的模块调用换成了远程调用形成了一个“分布式的大泥球”。一个订单查询原本一条SQL搞定的事情现在要串行调用五六个服务总延迟从几十毫秒飙升到上百毫秒。这次教训让我明白微服务拆分的核心不是技术分层而是业务领域的边界划分。我们引入了领域驱动设计DDD的思想组织业务、产品、技术同学一起通过事件风暴梳理出真正的“限界上下文”。每个服务必须围绕一个稳定的、内聚的业务能力来构建而不是按Controller-Service-DAO去切。分布式事务从Transactional到Saga的阵痛在单体里一个Transactional注解就能搞定的事务在微服务世界里成了噩梦。用户下单需要扣库存、创建订单、扣积分——三个服务、三个数据库怎么保证一致性我们踩过两阶段提交2PC的坑性能损耗大得离谱。最终选择了Saga模式将长事务拆成多个本地事务每个事务提交后通过消息触发下一步。配合发件箱模式Outbox保证消息的可靠投递。虽然放弃了强一致性但系统在最终一致性下跑得很稳。服务治理比拆分更难的是管住它们服务拆到几十个之后真正的噩梦才刚开始——服务治理。改一个数据库连接配置要改23个服务漏掉一个就是线上故障。服务间调用链错综复杂出问题根本不知道从哪里查起。我们花了大量精力搭建基础设施用Nacos做服务注册与发现Spring Cloud Gateway做统一入口SkyWalking做链路追踪。有了全链路追踪之后故障平均修复时间降低了70%以上。容器化与K8s从“手工活”到“自动化”服务多了环境不一致的问题也爆发了——“我本地能跑啊”成了团队最常听到的鬼话。我们引入Docker解决了环境一致性问题又把服务迁到了Kubernetes上。说实话刚开始用K8s时我是懵的Pod、Service、Ingress这些概念学得头大。但熬过阵痛期后收益巨大K8s的自动扩缩容让大促时资源利用率大幅提升滚动更新实现了零停机发布。一些反思走到今天回头看这条路走得跌跌撞撞。几点心得想分享第一不要为了拆而拆。拆分是为了更好的协作和演进不是为了追求技术时髦。如果团队不到十个人、业务复杂度还没到那个份上模块化单体可能是更务实的选择。第二微服务不会减少复杂性它只是把复杂性从代码里转移到了网络、运维和分布式系统里。第三先建好基础设施再拆。服务注册发现、配置中心、链路追踪、日志聚合——这些如果没准备好就贸然开拆后面补课的代价远大于一开始的投入。第四渐进式改造比“推倒重来”靠谱得多。一个模块一个模块地从老系统里剥离出来先拆网关再拆核心服务循序渐进。新老系统并行期间保证数据同步确保平滑过渡。从单体到微服务我们用运维的复杂度换取了业务的敏捷性和系统的弹性。这条路没有终点——云原生、服务网格Service Mesh、Serverless技术的演进还在继续。但经历过这一路的折腾和爬坑之后我对“架构的本质不是技术选型而是用合适的方式控制复杂度”这句话有了真真切切的体会。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价