从“踩坑”到“落地”:我在生产环境使用 Spring Cloud Alibaba 的真实经历
开篇:一次架构升级的契机

我是公司后端研发团队的一员,主要负责平台核心业务模块的开发与维护。我们是一个中型互联网公司,早期采用的是传统的单体架构,随着业务发展和用户量增长,服务开始频繁出现性能瓶颈,代码臃肿、部署困难、版本更新风险高等问题逐渐暴露出来。
为了应对这些挑战,公司决定进行微服务架构改造,而 Spring Cloud Alibaba(以下简称 SCA)成为我们的首选技术栈。一方面它基于 Spring Cloud,学习成本低;另一方面对阿里云生态支持好,对于我们正在逐步上云的技术路线非常契合。
今天就来分享一下我在这个过程中的一些实践经验,包括项目背景、遇到的问题、技术选型背后的考虑、关键实现点以及那些让人头大的“坑”。
项目背景:一个典型的电商后台系统

改造的目标是公司的订单中心和库存管理系统。这两个系统虽然拆分得不彻底,但已经存在多个子功能模块,比如:
- 订单状态同步
- 库存扣减
- 售后订单处理
- 异常订单监控
在之前的单体架构下,所有逻辑都在同一个工程里,通过本地事务管理数据一致性,日志和服务间调用都是内聚的。但在高并发场景下,经常出现线程阻塞、服务超时、接口响应慢等问题。
于是我们决定将整个系统拆分成以下几个微服务:
| 服务名称 | 职责说明 |
|---|---|
| order-service | 负责订单创建、状态变更等 |
| inventory-service | 处理库存相关业务 |
| logistics-service | 物流信息推送与查询 |
| gateway-service | 网关,统一对外提供 API 接口 |
| config-server | 统一配置中心 |
接下来就是选择合适的技术栈,Spring Boot + Spring Cloud 当然是主角,但在国内环境下,Spring Cloud Alibaba 可以说是如鱼得水,尤其在服务发现、限流、降级等方面提供了更成熟的解决方案。
遇到的第一个大问题:服务注册发现怎么搞?

问题描述
最初我们在服务注册这一块选择了 Eureka,但很快发现两个问题:
- 服务节点上下线感知慢:Eureka 默认的注册时间偏长,节点宕机后仍会保留一段时间的服务实例;
- 中文文档少、社区活跃度低:我们团队对英文文档不太友好,出问题很难快速定位。
于是我们转向了 Nacos,这是 Spring Cloud Alibaba 提供的服务注册与配置中心组件,支持动态服务发现、健康检查、分布式配置管理,非常适合国内项目。
解决方案
引入 spring-cloud-starter-alibaba-nacos-discovery 后,只需要添加如下依赖和配置:
<!-- pom.xml -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
# application.yml
server:
port: 8080
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # nacos 地址
然后启动类加上注解即可完成服务注册:
@EnableDiscoveryClient
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
服务之间调用我们使用 OpenFeign + LoadBalancer,Nacos 自动集成了 Ribbon,服务调用变得简单又高效。
第二个痛点:服务雪崩怎么办?熔断限流刻不容缓

问题描述
当我们将各个服务上线后,第一次压测就遇到了严重问题——库存服务被大量并发请求击穿,导致整个系统崩溃。这个问题让我们意识到,必须对服务链路进行保护。
技术选型:Sentinel 上场
我们果断引入了 Sentinel,它提供了丰富的限流、熔断、系统自适应保护等功能,并且与 Spring Cloud 集成非常方便。
关键配置与使用方式:
添加依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
开启 Sentinel Web 过滤器保护入口 API:
# application.yml
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # sentinel 控制台地址
eager: true
然后你可以直接使用 @SentinelResource 注解来定义资源并绑定异常处理器:
@GetMapping("/deduct")
@SentinelResource(value = "deductInventory", fallback = "handleError")
public Result deductInventory(@RequestParam String productId, @RequestParam Integer count) {
// 实际业务逻辑
}
public Result handleError(Throwable t) {
return Result.fail("当前库存服务繁忙,请稍后再试");
}
此外,Sentinel Dashboard 还可以实时观察每个资源的 QPS、线程数、异常率等指标,并设置动态规则,极大地增强了系统的可观测性和可控性。
数据库设计的小细节:分库分表初体验
虽然不是 Spring Cloud Alibaba 的范畴,但微服务化后数据库也面临压力剧增的问题。我们原来的库存和订单表都集中在一张主表中,读写混合严重,性能下降明显。
因此我们做了如下调整:
分库策略
按用户 ID Hash 划分,将订单分布到不同库中:
| 用户ID % 4 | 所属库名 |
|---|---|
| 0 | order_db_0 |
| 1 | order_db_1 |
| 2 | order_db_2 |
| 3 | order_db_3 |
这样既保证负载均衡,又能避免热点数据。
表结构拆分
原订单表:
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
status VARCHAR(20),
create_time DATETIME,
update_time DATETIME
);
现在根据业务属性拆分为两张表:
orders_base: 存储订单的核心字段(如订单编号、用户ID、商品ID)order_status: 存储状态变更记录,单独建索引便于查询
这样不仅提升了写入性能,也减少了锁竞争。
生产部署那些事儿:运维上的小技巧
微服务跑起来以后,真正的挑战才刚刚开始:如何保障稳定性?如何排查故障?
1. 日志聚合
我们在每一台服务器部署了 Filebeat,将日志采集后发送至 ELK(Elasticsearch + Logstash + Kibana),通过 Nacos 公共配置,统一指定日志输出路径和格式,极大地方便了线上问题的追溯。
2. Prometheus + Grafana 监控体系
我们为每个微服务集成 micrometer-registry-prometheus,并通过 Prometheus 定期拉取指标,使用 Grafana 展示 QPS、响应延迟、线程池状态等关键指标。
示例代码片段:
management:
metrics:
tags:
application: ${spring.application.name}
endpoints:
enabled-by-default: true
web:
exposure:
include: "*"
Prometheus 配置文件中加入:
scrape_configs:
- job_name: 'sca-services'
metrics_path: '/actuator/prometheus'
static_configs:
- targets:
- 'order-service:8080'
- 'inventory-service:8080'
有了这个体系后,我们可以在 Grafana 中一眼看出哪些接口最耗时、哪里出现异常抖动。
3. 滚动发布+灰度上线
为了避免一次性全量上线带来的不稳定因素,我们采用了滚动发布策略,配合 Kubernetes 的滚动更新机制,让新老版本并行运行,直到确认没问题再全部切换。
另外我们还使用了 Nacos 动态路由能力,在网关层实现了灰度流量控制,比如可以针对某些测试账号定向打向新版本服务。
踩过的坑 & 对策总结

坑点1:Nacos 服务注册失败频繁?
一开始我们把所有的服务都部署在同一台机器上,没有合理分配内存。结果 Nacos 经常因为 OOM 被重启,导致服务频繁失联。
对策:给 Nacos 单独部署独立机器或容器,调整 JVM 内存参数(比如 -Xms2g -Xmx2g)
坑点2:Feign 调用超时默认值太短?
默认的 Feign 超时是 1 秒,这在某些复杂业务场景下根本不够,尤其是首次启动服务还没完成预热的时候。
对策:手动修改 Feign 和 Ribbon 超时配置:
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
ribbon:
ReadTimeout: 5000
ConnectTimeout: 5000
坑点3:Sentinel Dashboard 规则重启丢失?
刚用 Sentinel 时我们发现每次重启 Dashboard,之前配置的限流规则都会失效。
对策:结合 Nacos 配置中心持久化 Sentinel 规则。在 Dashboard 中启用 --nacos-namespace-id 参数,将规则推送到 Nacos 存储。
效果与收益总结
经过近半年的打磨,目前这套基于 Spring Cloud Alibaba 构建的微服务体系已经在生产稳定运行了超过三个月,日均处理订单量提升 3 倍,API 平均响应时间由原来的 400ms 缩短到 150ms。
具体收益包括:
- 稳定性增强:熔断限流机制有效防止了服务雪崩
- 弹性扩容:服务可以根据负载水平自动伸缩,节省了不少服务器资源
- 研发效率提升:标准化的微服务模板和公共组件复用,新人上手更快
- 可观测性加强:完善的监控告警和日志体系让排查问题不再盲目
一点感悟 & 给读者的建议
说实话,刚开始接触 Spring Cloud Alibaba 的时候,我也曾迷茫过,特别是面对这么多组件(Nacos、Sentinel、Seata、RocketMQ...),不知道该学哪个、用哪个。
但后来我发现,技术是服务于业务的工具,不是炫技的对象。在项目初期,不需要把所有组件都上马,而是应该围绕核心业务问题,选择最关键的几个解决点来入手。
如果你正准备使用 Spring Cloud Alibaba,这里是我的几点建议:
从 Nacos 开始,不要一开始就上 RocketMQ 或 Seata
微服务的基础是注册发现、配置管理,把这些先搞懂,后面的组件才能发挥更大作用。重视服务治理能力,尽早接入 Sentinel 或 Hystrix
不然你迟早会遇到“调用链爆炸”的问题。提前做好服务监控方案
Prometheus + Grafana 是非常成熟的选择,值得投入时间搭建。别怕改架构,但要有节奏地推进
我们也是边跑边修,逐步迭代,不是一口气重写的。
最后想说一句:微服务从来都不是银弹,它能带来灵活性,也会引入更多复杂度。只有深入理解你的业务场景,找到平衡点,才是技术落地的关键。
如果你也在做微服务转型,或者在用 Spring Cloud Alibaba,欢迎留言交流,一起成长 👇
本文首发于个人博客,作者:阿乐,一个喜欢写代码也喜欢写文章的程序员。

评论 0