从微服务到高可用:我的 Spring Cloud Alibaba 生产实践之路
引言:为什么我们选择了 Spring Cloud Alibaba?

事情还要从几年前说起,当时我所在的公司正在经历一次比较大的架构升级。原本的单体系统已经难以满足日益增长的业务需求和流量压力,团队决定尝试往微服务架构转型。
最初考虑的是 Spring Cloud Netflix 套件,但随着社区对 Eureka、Zuul 等组件逐渐停止积极维护(尤其是 Hystrix 被官方宣布进入维护模式),再加上我们有不少基于阿里系中间件的历史项目,最终在技术选型阶段果断转向了 Spring Cloud Alibaba。
这个决定不仅改变了我们的架构演进方向,也让我在后来几年中不断深入研究这套组合拳,并在多个实际项目中积累了宝贵的经验。今天我就想把这些踩过的坑、绕过的弯路,以及一些真实的生产经验分享出来,希望能帮到正走在微服务转型路上的你。
项目背景:电商平台重构之痛

我们接手的是一套运行多年的电商平台后端系统,采用的是传统的单体架构,部署在几台老旧的物理服务器上。随着用户量和交易频次的增长,问题开始集中爆发:
- 接口响应慢,高峰期偶发超时
- 功能更新风险大,牵一发动全身
- 部署过程繁琐,灰度发布困难
- 扩展性差,核心服务无法水平扩容
于是,我们启动了“凤凰计划”——目标是将整个系统拆分为多个可独立部署、可伸缩的微服务模块,实现服务间解耦,并为后续的弹性扩容打下基础。
遇到的挑战:微服务带来新问题?

微服务确实带来了不少好处,但也带来了新的复杂性和运维成本。尤其是在初期搭建环境和服务治理时,我们遇到了很多棘手的问题:
1. 服务注册发现不稳定?
我们最早用 Nacos 作为注册中心,但在压测环境下偶尔出现服务实例未及时注册或被错误剔除的问题,导致调用失败。
2. FeignClient 的连接池配置不当?
Fein 默认使用的是 JDK 自带的 HttpURLConnection,性能较差,且默认没有启用连接复用,导致并发稍高时出现大量 CLOSE_WAIT。
3. 网关限流策略不完善?
网关使用的是 Zuul,虽然能满足基本路由功能,但动态限流能力较弱,而且 Zuul 本身的性能也不足以支撑高并发场景。
4. 分布式事务怎么搞?
订单、支付、库存等服务各自独立,业务上又需要保证一致性。早期尝试用了 Seata,但在某些场景下回滚异常频繁,日志混乱难定位。
这些问题,一度让我们怀疑是否应该继续微服务路线。幸运的是,通过不断的探索与改进,我们逐步找到了适合自己的解决方案。
技术方案设计:Spring Cloud Alibaba 组合拳

我们采用的技术栈主要如下:
| 模块 | 使用组件 |
|---|---|
| 服务注册 | Nacos Server + 客户端 |
| 服务通信 | OpenFeign + Ribbon + HTTP Client |
| 网关 | Gateway + Sentinel |
| 配置管理 | Nacos Config |
| 熔断降级 | Sentinel |
| 分布式事务 | Seata(TCC 模式) |
| 监控追踪 | SkyWalking + Prometheus + Grafana |
下面重点讲几个关键模块的设计和实现思路。
关键代码示例与配置说明
1. 使用 Nacos 作为服务注册中心
spring:
application:
name: product-service
cloud:
nacos:
discovery:
server-addr: 192.168.0.100:8848
服务启动后会自动注册到 Nacos,其他服务通过服务名即可调用,Ribbon 会自动完成负载均衡。
2. 使用 OpenFeign 发起远程调用
@FeignClient(name = "order-service")
public interface OrderServiceClient {
@GetMapping("/orders/{userId}")
List<Order> getOrdersByUserId(@PathVariable("userId") Long userId);
}
为了提升性能,我们将底层 HTTP Client 替换为 OkHttp:
feign:
client:
config:
default:
httpclient:
enabled: false
okhttp:
enabled: true
同时,设置了合理的连接池参数,避免资源浪费和 CLOSE_WAIT 问题。
3. 网关层结合 Sentinel 实现限流熔断
我们在网关层引入了 Sentinel 来做入口级别的限流,防止突发流量冲垮下游服务:
spring:
cloud:
gateway:
routes:
- id: product-route
uri: lb://product-service
predicates:
- Path=/api/product/**
filters:
- StripPrefix=1
- name: Sentinel
args:
block-handler: com.example.gateway.handler.GatewayBlockHandler
并自定义了一个 BlockHandler:
public class GatewayBlockHandler {
public static Mono<ServerResponse> handle(ServerRequest request, Throwable ex) {
return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
.bodyValue("请求过多,请稍后再试");
}
}
这样可以在请求超过阈值时直接返回提示,而不是抛出异常或阻塞线程。
踩过的坑和解决办法
坑 1:Nacos 启动慢,影响本地调试
现象:本地开发环境 Nacos 启动耗时较长,每次重启都需要等待几分钟,影响效率。
解决:采用 Docker 快速启动一个轻量版 Nacos 服务:
docker run -d -p 8848:8848 --env MODE=standalone nacos/nacos-server
另外,也可以使用 nacos-mock 工具在本地模拟注册中心行为。
坑 2:Seata TCC 模式下的幂等性处理
我们在分布式下单操作中使用 Seata 的 TCC 模式,但在测试中发现部分事务重复执行,导致库存扣减两次。
分析原因:TCC 的 cancel 阶段可能因网络波动而重试多次,如果 cancel 方法没做幂等处理,就会发生数据错乱。
解决方案:
- 在 Cancel 方法内部增加唯一业务标识(如订单号)和版本号控制
- 使用数据库乐观锁或者 Redis 标记机制防止重复执行
坑 3:Sentinel 控制台持久化问题
上线之后我们发现一旦 Sentinel 控制台重启,之前配置的规则就丢了。
解决方法:结合 Nacos 实现规则持久化。
配置文件中添加如下内容:
spring:
cloud:
sentinel:
datasource:
ds1:
nacos:
server-addr: 192.168.0.100:8848
data-id: ${spring.application.name}-sentinel
group: DEFAULT_GROUP
然后在 Nacos 中手动创建对应的 dataId,写入规则 JSON:
[
{
"resource": "/api/order/create",
"limitApp": "default",
"grade": 1,
"count": 200,
"strategy": 0,
"controlBehavior": 0
}
]
成果与收益:架构升级带来的改变
改造完成后,系统在以下几个方面有了显著提升:
- 性能稳定性增强:服务间通信延迟降低,网关层能扛住更高的并发请求。
- 故障隔离能力增强:某个服务崩溃不会影响整个系统,Sentinel 和 Ribbon 协作完成优雅降级。
- 研发效率提升:服务独立部署、灰度发布更方便,迭代速度加快。
- 运维更加透明:SkyWalking 实现全链路追踪,定位问题时间缩短 80%。
更重要的是,这次转型让我们真正理解了技术服务于业务的本质。不是为了上微服务而上,而是要根据业务特点选择合适的技术组合。
我的经验分享:给你的几点建议
如果你也在用或者准备使用 Spring Cloud Alibaba,以下是我总结的一些实战经验,供参考:
1. 别盲目堆技术,先看清业务需求
不要看到别人用啥你就用啥。比如 Seata 并不是所有场景都适用,简单业务完全可以用最终一致性的消息队列方案替代,反而更稳定。
2. 注意版本匹配问题
SCA(Spring Cloud Alibaba)对 Spring Boot 和 Spring Cloud 的版本非常敏感,一定得查文档看兼容矩阵。我们有段时间踩过版本冲突,导致 Feign 调用一直报空指针,查了一天才发现是包冲突。
3. 运维自动化先行
Kubernetes + Helm 是个不错的组合,配合 Jenkins CI/CD 可以大幅提升部署效率。别小看这一块,上线后的日常运维比开发还花时间。
4. 日志和监控不能少
微服务最大的问题就是链路长、状态多,一定要建立统一的日志收集(ELK)、监控告警(Prometheus+Grafana)体系,否则出了问题很难排查。
5. 多读文档和源码
Spring Cloud Alibaba 虽然社区活跃,但有些问题官网文档不一定覆盖,建议没事看看 GitHub issue 或者翻翻源码,说不定就能找到问题答案。
结语:技术从来都不是终点,而是工具
回头来看,Spring Cloud Alibaba 并非完美无缺,但它的确帮助我们成功完成了平台级的架构升级。最重要的是,它教会了我如何用工程思维去平衡技术与业务之间的关系。
在这条路上,我们会遇到无数新技术、新框架、新名词,但不要忘了我们最本质的职责:写出稳定、高效、易于维护的代码,来支持真实业务的发展。
希望这篇文章能对你有所启发。如果你有类似经验,也欢迎留言交流。技术路漫漫其修远兮,愿你我都能保持热爱,砥砺前行。
文章作者:阿林
原创首发于:个人博客 & 知乎专栏《Java 微服务那些事儿》
欢迎关注,持续输出一线开发实战经验

评论 0