从零到上线:Spring Cloud Alibaba 在高并发电商系统的实战之路
引言:一次系统重构的契机

2021年初,我加入了一个中型电商平台的技术团队,负责整个后端服务架构的重构与优化。这个平台当时采用的是传统单体架构,随着业务快速扩展,订单量、访问量激增,系统出现了明显的性能瓶颈。具体表现包括接口响应时间飙升、数据库压力剧增、部署维护困难,甚至在大促期间发生过宕机事故。
于是,我们决定引入微服务架构进行拆分与重构。结合技术选型调研和已有技术栈基础(如 MySQL、Redis、Docker),最终我们选择了 Spring Cloud Alibaba 作为核心框架,配合 Nacos、Sentinel、Seata、RocketMQ 等组件,构建一套适合业务需求的微服务体系。
这篇文章将基于我在该项目中的实际工作经验,分享这套体系搭建过程中遇到的真实问题、解决方案以及一些关键决策背后的思考。
背景介绍:老系统的问题到底有多严重?

项目初期,我们的单体应用部署在一个 Tomcat 实例上,所有的模块包括商品中心、库存管理、用户中心、订单服务都集中在一起。随着用户量增长到日均 PV 十万+,QPS 经常突破 5000,尤其在秒杀活动时会飙升到上万级别,系统的反应就变得非常迟缓。
几个典型问题包括:
- 接口响应慢:部分请求耗时超过 5 秒甚至超时。
- 资源争用严重:所有服务抢一个线程池资源,容易出现雪崩效应。
- 代码臃肿难维护:单个工程模块多,耦合严重,改动一个功能常常牵一发而动全身。
- 扩展性差:无法针对热点模块做横向扩容。
- 数据一致性难以保证:尤其是在下单减库存的过程中频繁出现超卖。
这些问题已经严重影响用户体验和运营效率,我们必须做出改变。
第一次尝试:试水 Spring Cloud + Nacos 初体验
最开始我们尝试使用 Spring Cloud Netflix 套件(如 Eureka、Feign、Zuul)搭建微服务,但发现以下几个痛点:
- Eureka 的自我保护机制导致服务实例状态不准;
- Feign 在调用失败时处理不够灵活;
- Gateway 性能不够理想;
- 缺乏对流量治理、限流熔断等高级功能的支持。
后来我们在一次技术交流会上了解到 Spring Cloud Alibaba 的生态整合非常成熟,且阿里开源的组件已经在多个大型生产环境验证过稳定性,因此我们决定切换为 Spring Cloud Alibaba 技术栈,并开始第一轮微服务拆分。
最初的拆分逻辑如下:
| 模块名称 | 功能说明 |
|---|---|
| gateway | 统一路由入口 |
| user-service | 用户信息、权限控制 |
| product-service | 商品详情、分类、搜索 |
| order-service | 订单创建、支付回调、状态变更 |
| inventory-service | 库存管理、库存扣减 |
| log-service | 日志收集、审计 |
我们采用 Nacos 作为统一的服务注册与配置中心,逐步将上述服务独立部署,每个服务对应一个 Docker 容器,通过 Jenkins 自动化打包发布。
初步拆分完成之后,效果明显:
- 单个服务的启动时间和部署速度大大提升;
- 可以根据业务情况单独扩容某个热点服务;
- 各服务之间通过 OpenFeign + LoadBalancer 进行调用,调用链更清晰。
但这只是第一步,真正的挑战才刚刚开始。
高并发场景下的真正考验
问题一:秒杀场景下单失败率飙升
我们第一次将新系统用于“618”促销活动,目标是在短时间内完成大规模的秒杀操作。然而,实际运行过程中,大量请求集中在 order-service 和 inventory-service 上,出现了严重的请求堆积,导致很多订单下单失败,或者库存扣减不一致。
分析原因:
- Feign 默认的连接超时和重试策略不合理,在极端负载下未能及时拒绝无效请求;
- 数据库写入并发过高,事务竞争激烈;
- Redis 缓存穿透 + 击穿 + 雪崩没有做好应对方案;
- 没有设置合理的限流降级规则。
解决方案一:引入 Sentinel 限流 + 熔断
我们将 Sentinel 集成进每个服务,配置了两种类型的规则:
- 入口级限流规则:通过 URL 接口维度限制每秒最大请求数(QPS),比如下单接口设定为 500 QPS。
- 服务依赖熔断规则:当某接口异常比例超过阈值(如 30%)时自动熔断 5 分钟,并返回兜底数据或提示语。
此外,我们在网关层加了一层全局限流,防止恶意攻击或突发流量冲击后端。
解决方案二:数据库优化 + 本地锁 + 分布式锁配合使用
在订单创建和库存扣减逻辑中,我们采用了以下组合手段:
- 使用 MySQL 行锁(select for update)来确保同一时间只允许一个线程修改某条库存记录;
- 使用 Redisson 提供的可重入分布式锁,在多实例场景下防止重复扣减;
- 将高频读取的数据提前缓存至 Redis,降低数据库压力;
- 对 Redis 设置空值缓存和互斥锁避免穿透;
- 异步落盘,通过 RocketMQ 将订单创建消息发送给订单写入队列,实现异步持久化。
这些优化完成后,在后续的一次压测中模拟了 10,000 并发请求,系统整体成功率提升了近 40%,且无重大故障发生。
微服务之间的通信难题
微服务多了以后,如何保障服务间通信的稳定性和可观测性也成了新的问题。
比如在调用链监控方面,我们曾一度陷入日志分散、定位困难的困境:A 调 B,B 调 C,C 再调 D,一旦其中一个环节出错,排查起来非常麻烦。
后来我们果断引入了 SkyWalking 来做全链路追踪监控。它不仅支持自动生成调用链图谱,还能查看每个节点的耗时、SQL、调用次数等信息,极大地提高了故障定位效率。
同时我们还利用 Spring Boot Admin 做简单的服务健康检查,监控内存、线程池、GC 状态等指标,做到实时告警和预警。
分布式事务的落地实践
另一个棘手的问题出现在“订单支付成功后的积分赠送”流程中。
订单支付完成后需要更新订单状态、增加用户积分、触发营销活动,这三个操作涉及不同服务,必须保证强一致性。
最初我们考虑使用 Seata 的 AT 模式来进行分布式事务管理,但在集成测试阶段遇到了以下几个问题:
- 多表关联操作在 AT 模式下锁粒度过粗,造成死锁;
- 不同服务间的 SQL 差异性大,导致 UndoLog 构建复杂;
- Seata 的 TC(事务协调器)如果宕机会导致整个事务失败。
最终我们调整策略,改为 基于 RocketMQ 的事务消息机制 + 最终一致性补偿方案:
- 支付服务发送一条预提交消息到 MQ;
- 消费方监听该消息并执行本地事务(更新积分、触发营销);
- 执行成功后,向 MQ 确认提交,否则回滚;
- 加入定时补偿 Job,每天凌晨对未确认的消息重新处理。
这种方式虽然失去了强一致性,但换来了更高的可用性和扩展性,更适合我们当前的业务规模。
生产运维的一些经验教训
除了架构设计本身,我也想谈谈一些生产运维方面的体会。
容器化部署 + Helm 管理集群
我们使用 Kubernetes + Helm 部署服务,Helm Chart 模板极大简化了服务发布流程,每个微服务只需填写 values.yaml 文件即可一键部署。
举个例子,我们的 order-service 的 Helm Chart 包含了 deployment、service、ingress、configmap 等资源定义,可以通过参数动态设置副本数、JVM 参数、环境变量等。
# values.yaml 示例片段
replicaCount: 2
image:
repository: registry/order-service
tag: latest
env:
SPRING_PROFILES_ACTIVE: "prod"
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1"
通过 Helm 部署,我们实现了自动化蓝绿发布、金丝雀发布等功能,有效降低了线上故障的风险。
监控报警体系建设
我们使用 Prometheus + Grafana 做监控,Prometheus 抓取各个服务暴露的 Actuator 指标(如 HTTP 请求次数、响应时间、JVM GC、线程池状态),并通过 AlertManager 设置报警规则:
- 当 JVM 堆内存使用率 >90% 时通知值班人员;
- 当 HTTP 请求平均耗时 >500ms 触发短信报警;
- 当服务不可用持续 2 分钟以上触发钉钉机器人提醒。
同时我们也将 Sentinel 的实时规则变动日志同步到 Kafka 中,便于后续分析调优。
日常小插曲:Nacos 节点挂掉怎么办?
有一次,我们线上使用的 Nacos 集群中的一个节点因为磁盘空间不足被 OOM Kill,导致服务注册出现抖动。
这个问题让我意识到两个问题:
- Nacos 元数据持久化能力有限:当时我们是默认使用内嵌的 Derby 数据库,这显然不适合生产环境;
- 缺乏健康检查机制:Kubernetes 中缺少对 Nacos Pod 的探针监控;
所以我们后来升级方案,把 Nacos 后端换成 MySQL 存储元数据,同时为 Nacos 容器加上 readinessProbe 和 livenessProbe 探针,并配合 K8s 的滚动重启机制,避免服务中断。
结果对比:性能提升 + 可维护性显著增强
经过半年的微服务重构和一系列优化措施,系统有了质的飞跃:
| 指标 | 改造前 | 改造后 | 提升幅度 |
|---|---|---|---|
| 单接口平均响应时间 | 800ms - 1.5s | 120ms - 250ms | 提升约 75% |
| 秒级订单创建峰值 | 3000/秒 | 7000/秒 | 提升 133% |
| 故障恢复时间 | 数小时 | 10分钟以内 | 显著缩短 |
| 新功能上线周期 | 1月左右 | 1周左右 | 缩短 75% |
更重要的是,系统具备了良好的扩展性,后续新增优惠券服务、推荐服务都可以快速接入,不再受限于原有的单体结构。
我的经验总结与建议
如果你也在考虑使用 Spring Cloud Alibaba 构建微服务体系,这里是我的几点建议:
不要一开始就追求完美架构
微服务不是银弹,要根据业务发展阶段逐步拆分,过度设计反而增加复杂度。组件选型要贴合真实场景
比如是否真需要强一致性?是否能接受一定的延迟?这些决策会影响你使用 Seata 还是 RocketMQ。重视监控和预警体系的建设
没有可观测性的微服务系统就像一艘没导航的船。尽早搭建好监控体系,避免盲飞。合理评估云厂商提供的产品
如果公司愿意投入预算,可以考虑使用阿里云 EDAS、MSE 等托管产品,省去不少自建运维成本。团队协同意识要跟得上
微服务意味着更多的协作,DevOps 文化和自动化工具链必不可少。多写点文档和注释吧,特别是中间件规则类内容
很多时候你写了一个复杂的 Sentinel 限流规则,半年后自己都不记得为什么那么配。
写在最后:技术是解决问题的工具,而不是目的本身
在这段旅程中,我深刻体会到,一个好的架构师不仅要懂技术,更要懂业务、懂协作、懂权衡。Spring Cloud Alibaba 是一个很好用的工具包,但它终究只是一个工具。
真正让系统稳健运行、支撑起海量请求的,是我们一次次的讨论、推敲、调试和优化。每一个深夜盯着日志排查问题的时刻,每一次线上灰度发布的紧张瞬间,都是成长路上宝贵的财富。
希望这篇来自真实战场的经验分享,能给你带来一些启发和共鸣。
📌 欢迎留言互动,也欢迎大家分享自己的 SCA 实战经历,一起进步 💪

评论 0