技术探索与实践踩坑记录:从一次“翻车”的架构演进谈起

周洋
2025-06-16 09:22
阅读 741

开篇:为什么想写这篇文章

开篇:为什么想写这篇文章

在我做技术的这些年里,踩过的坑远比走过的坦途要多。但说实话,每次踩坑之后,带来的反思和成长也特别深刻。今天我想分享的是我亲身经历的一个典型技术升级项目——如何从单体架构迁移到微服务架构,并在这个过程中遇到的各种问题、挑战以及应对方式。

这个项目并不是那种“理想情况下才成立”的案例,而是一个真实的业务场景中,我们团队在权衡成本、时间、稳定性后做出的技术决策。文章不会只讲“成功的一面”,也会还原当时因为选型不当、设计考虑不周而导致的服务雪崩等惨痛教训。

如果你也在面临架构升级、性能优化或者微服务拆分这些棘手的问题,希望我的这次经历能给你一些启发。


项目背景与初始挑战

项目背景与初始挑战

背景介绍

项目是一个 ToB 的 SaaS 平台,主要面向中小型零售企业,提供订单管理、库存控制、员工排班等功能。系统最开始采用的是传统的 Spring Boot 单体架构,前后端分离,MySQL + Redis 做存储层,Nginx 反向代理加负载均衡。

随着用户数量的增长(年活跃商户超过 2000 家),平台逐渐暴露出以下几个问题:

  • 代码膨胀严重:业务模块耦合度高,维护困难,修改一个功能经常牵一发动全身
  • 部署效率低:整个应用打包成一个 jar 包,频繁上线时影响其他模块
  • 性能瓶颈显现:高峰期请求延迟增加,数据库连接池经常打满
  • 开发协作复杂:多个小组共用一个代码库,频繁出现合并冲突、版本混乱

于是,在公司战略推动下,我们决定启动“架构升级改造”项目,目标是将单体架构逐步拆分为基于 Spring Cloud Alibaba 的微服务架构。


技术选型:从头开始的抉择

在确定改造方向之前,我们先进行了为期两周的技术调研和讨论,列出了以下几个核心维度:

  • 技术栈是否成熟稳定?
  • 是否有足够多的开源组件支持?
  • 运维难度是否可控?
  • 团队是否有对应的经验积累?

围绕这几个方面,我们对比了几个主流方案:

技术栈 优点 缺点
Dubbo + Zookeeper 阿里系,社区活跃,RPC 性能高 注册中心不够友好,配置略复杂
Spring Cloud Netflix 成熟稳定,Spring 社区广泛支持 已进入维护状态,部分组件如 Hystrix 不再更新
Spring Cloud Alibaba 阿里云背书,Nacos 等组件更现代 文档相对较少,依赖较多
Kubernetes + Istio 微服务治理能力强,适合长期发展 学习曲线陡峭,初期投入大

最终,我们选择了 Spring Cloud Alibaba(SCA),主要原因如下:

  • 团队有一定的 Spring Boot 经验,学习曲线相对平缓;
  • 公司内部已经有使用阿里云的部分产品(如 OSS、MQTT),技术栈统一性更好;
  • Nacos、Sentinel 等组件在社区活跃度不错,能满足现阶段需求;
  • 比起 Kubernete+Istio 更适合中小团队快速上手。

这个选型虽然后期带来了一些挑战,但总体来看是正确的。


拆分过程中的关键问题与“第一次翻车”

第一步:服务拆分边界模糊

最初我们计划按照业务模块进行拆分,比如订单服务、库存服务、用户服务等等。但在实际拆分过程中却发现:

“理想中的模块划分” 和 “现实中的调用链路” 完全不是一回事。

很多接口存在跨模块频繁调用,例如订单创建需要同时操作库存、用户权限、优惠券等多个模块。如果强制按业务拆分,就会产生大量 RPC 调用链,导致性能下降。

我们尝试过几种方式:

  1. 粗粒度拆分:一个服务负责多个相关模块(比如 Order + Inventory 放在一起)。好处是减少了服务间调用,坏处是又回到了“大服务”的老问题。
  2. 细粒度拆分:严格按模块拆,结果出现了多个接口要跨服务调用的情况,增加了服务间的依赖和网络开销。
  3. DDD 领域驱动拆分:这是后来才引入的方法,效果明显更好。

教训总结:

  • 初期不要急于拆分,建议画出核心业务流程图,明确哪些是核心聚合根(Aggregate Root)
  • 尽量保证一个服务对某个领域有完全的数据主权,避免数据分散在多个服务中
  • 如果不确定怎么拆,可以先通过代码结构重构来解耦模块,为后续拆分做准备

第二步:分布式事务引发的灾难

我们的订单创建涉及扣库存、生成流水、更新用户余额等多个操作,需要强一致性。一开始我们采用了 TCC 补偿事务模型,并选用 Seata 作为分布式事务框架。

本以为能轻松解决,没想到上线第一天就炸了。

问题表现是:

  • 创建订单失败率飙升(原本 1% → 瞬间 15%)
  • 日志中频繁出现 TimeoutBranchReportFailed
  • 大量数据不一致,甚至出现了负库存!

排查后发现几个问题:

  1. Seata 配置不当:TM(事务协调器)和 RM(资源管理器)通信超时设置不合理,没有根据业务实际耗时做调整。
  2. 补偿逻辑异常未处理:Cancel 方法被调用时抛出异常,未能捕获,导致事务无法回滚。
  3. 锁竞争激烈:多个并发订单争抢同一商品库存,导致 TCC 中 Try 操作锁等待时间过长。

最后我们做了以下调整:

  • 改为使用 Saga 模式替代 TCC,减少复杂性和失败概率(适用于无需锁定资源的业务)
  • 对 Cancel 阶段做幂等性和异常兜底处理
  • 引入本地事务表 + 最终一致性机制,结合 MQ 实现异步补偿

教训总结:

  • 分布式事务不是银弹,优先从业务角度出发,尽量弱化一致性要求
  • 在高并发、复杂业务场景中,建议使用最终一致性 + 人工核对 + 自动补偿机制
  • 如果坚持用 TCC,务必做好日志追踪和 Cancel 的容错处理

第三步:服务发现与网关集成的“蜜月期崩溃”

我们使用 Nacos 作为注册中心和配置中心,刚开始一切顺利,但到了压测阶段才发现问题:

  • 服务频繁失联,健康检查不及时
  • 网关路由规则没生效,导致接口 404
  • 微服务实例数突然暴涨,造成 CPU 打满

分析后发现:

  • Nacos 默认心跳周期是 5s,但我们在压力测试中模拟了大量服务上下线,导致注册中心负担过重
  • 使用 Zuul 作为网关,其过滤器机制对高并发支持不佳,响应延迟严重
  • 某个基础服务因异常重启不断重连 Nacos,形成“雪崩效应”

我们采取了以下措施:

  • 将 Nacos 由单节点升级为集群模式
  • 将 Zuul 替换为 Spring Cloud Gateway,性能提升明显
  • 为每个服务设置了健康检查阈值,避免短暂抖动导致剔除
  • 加入熔断限流策略(使用 Sentinel)

教训总结:

  • 注册中心不能单点运行,尤其是在生产环境
  • 网关选型很重要,Zuul 在高并发下不如 Gateway
  • 微服务必须具备自我保护能力,比如降级、熔断、限流

解决后的成果与收益

经过将近三个月的持续优化与迭代,我们基本完成了架构改造,并带来了以下几个方面的收益:

1. 部署效率显著提高

过去改一个小功能也要重新部署整个系统,现在只需发布对应的微服务,CI/CD 构建速度提升了近 60%。

2. 故障隔离性增强

以前一个模块的 bug 可能导致整个系统不可用,现在即使某个服务挂掉,其他服务也能继续运作。

3. 性能提升明显

我们把慢 SQL 集中的模块独立出来,配合本地缓存 + Redis 缓存,接口平均响应时间从 800ms 降到 300ms 内。

4. 技术氛围变好了

拆分之后,不同小组负责不同的服务,大家更有自主权了,也开始愿意写单元测试、文档、监控指标。


经验分享:给正在做架构改造的同学几点建议

1. 拆分前一定要搞清楚“谁是谁的上游”

你可以画一张调用关系图谱,看看哪些服务之间交互频繁,哪些接口调用最多,这样可以辅助你合理划分服务边界。

2. 不要用技术解决所有问题,学会“妥协”

有时候用业务方式解耦反而比技术手段更容易落地。比如我们可以允许某些非核心业务模块暂时保持弱一致性,而不是一味追求强一致性。

3. 微服务≠一切都要拆,公共模块还是可以复用

有些工具类、基础类、通用模型没必要单独作为一个服务,可以通过 Maven 或 Gradle 包的形式共享。

4. 治理手段要跟上,否则微服务会变成“微地狱”

  • 监控必须到位(Prometheus + Grafana 是不错的选择)
  • 日志集中收集(ELK 系统)
  • 接口调用链追踪(SkyWalking 或 Zipkin)
  • 服务注册中心高可用
  • 熔断限流必须配齐

5. 团队意识要比技术先行

技术可以学,但如果团队对微服务的理解不一致,沟通成本极高。建议在拆分前组织几场内部分享会,统一认知,明确职责边界。


写在最后:技术从来都不是孤立的存在

回头看这次项目的“跌宕起伏”,其实最大的收获不是学会了多少新工具,而是更加理解了:

技术的本质是为了更好地服务业务,而不是制造更多问题。

每一次踩坑,都是对业务理解的一次加深;每一次失败,都是对技术视野的一次扩展。

所以如果你正在经历类似的架构升级或者技术探索,请记住一句话:

“别怕踩坑,关键是你要知道怎么走出来。”

也希望这篇文章能陪你走过一程,愿你在技术的路上越走越稳。

— by 一名还在路上的老程序员 🧑‍💻

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝