Spring Cloud Alibaba 生产实践:从大厂离职前,我给团队留下的“遗产”
去年十月,我正式递交了辞职信。在某大厂干了快两年,每天跟 Kubernetes、微服务、灰度发布、熔断降级打交道,头发日渐稀疏,但经验倒是攒了不少。现在处于“辞职休息中思考职业方向”的状态——说白了就是在家躺平,顺便刷刷 LeetCode、看看新框架,为下一段旅程做准备。
今天这篇博客,其实是我离职前最后一周偷偷整理的文档。本来打算只留给组里兄弟们用,但想想,不如发出来,万一能帮到其他正在被 Nacos 和 Sentinel 折磨的同行呢?
起因:别再用 Eureka 了,老板说要“国产化”
事情得从去年双11前说起。我们系统原本是基于 Spring Cloud Netflix(Eureka + Hystrix + Zuul)那一套老古董搭建的。虽然跑得还行,但 Netflix 停更后,社区活跃度肉眼可见地往下掉。更糟的是,运维组的老哥每次升级 JDK 或 Spring Boot 版本都如履薄冰,生怕哪个兼容性问题把整个注册中心搞崩了。
某次站会上,CTO 突然抛出一句:“咱们是不是该考虑技术栈国产化了?Nacos 都开源好几年了,阿里系项目用得挺稳。”
产品经理当场接话:“对啊,还能省点 license 费!”(笑死,Spring Cloud Netflix 又不是商业软件……)
于是,这锅就落到了我们后端组头上。Leader 拍着我肩膀说:“你不是喜欢折腾新技术吗?这个迁移任务交给你,Deadline 是双11前两周上线。”
那一刻,我真想掏出 MacBook Air 砸他脸上——但转念一想,这不正好是我跳槽前加简历亮点的好机会?
为什么选 Spring Cloud Alibaba?
说实话,一开始我对 SCA(Spring Cloud Alibaba)也有偏见:总觉得是“国产轮子”,怕踩坑。但翻了几本书籍(比如《Spring Cloud Alibaba 微服务原理与实战》),又扒了扒它的 GitHub 仓库(star 数快 25k 了,issue 响应也挺快),发现社区维护其实挺靠谱。
更重要的是,它深度集成了阿里中间件生态:
- Nacos:服务注册 + 配置中心二合一
- Sentinel:比 Hystrix 更细粒度的流量治理
- Seata:分布式事务(虽然我们没用上)
- 还原生支持 Dubbo(不过我们是纯 HTTP 微服务,暂时用不上)
最关键的一点:它对 K8s 友好。我们早就在用 Helm + ArgoCD 做 GitOps 了,而 Nacos 官方提供了 K8s Operator,部署起来比 Eureka 方便太多。
实战:从零迁移到生产上线
第一步:替换注册中心 —— Nacos 上场
先把 spring-cloud-starter-netflix-eureka-client 删掉,换成:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2022.0.0.0</version>
</dependency>
然后配置文件改一下:
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: ${NACOS_HOST:localhost}:8848
namespace: prod # 生产环境隔离
group: DEFAULT_GROUP
坑点来了:Nacos 默认使用 AP 模式(基于 Distro 协议),但在 K8s 里如果 Pod 不稳定,容易出现服务列表不一致。我们后来强制切换到 CP 模式(基于 Raft),通过启动参数指定:
# 在 Deployment 中设置
env:
- name: NACOS_SERVERS
value: "nacos-0.nacos-headless, nacos-1.nacos-headless, nacos-2.nacos-headless"
- name: MODE
value: "cluster"
- name: FUNCTION_MODE
value: "all"
- name: PREFER_HOST_MODE
value: "hostname" # 必须设成 hostname,否则 Pod IP 会变
否则,Pod 重启一次,服务就“失联”一次,测试同学差点把我钉在耻辱柱上。
第二步:配置中心 —— 告别本地 YAML
以前所有配置都打在 jar 包里,改个数据库密码都要重新 build。用了 Nacos Config 后,终于实现“配置热更新”:
spring:
cloud:
nacos:
config:
server-addr: ${NACOS_HOST:localhost}:8848
file-extension: yaml
namespace: prod
group: DEFAULT_GROUP
然后在代码里加个 @RefreshScope:
@RestController
@RefreshScope
public class ConfigController {
@Value("${app.feature.toggle}")
private boolean featureToggle;
@GetMapping("/toggle")
public boolean getToggle() {
return featureToggle;
}
}
但注意:@RefreshScope 是懒加载的!只有当 Bean 被调用时才会刷新。我们曾遇到一个后台定时任务,因为没被触发,配置一直没更新,导致线上 feature 开关失效。后来改成监听 RefreshEvent 才解决。
第三步:流量防护 —— Sentinel 出手
Hystrix 只能做线程池隔离和简单熔断,而 Sentinel 支持:
- QPS/线程数限流
- 熔断降级(慢调用比例、异常比例)
- 系统自适应保护(CPU、load 自动限流)
- 热点参数限流(比如按 userId 限流)
集成也很简单:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
默认规则是空的,得自己配。我们选择 推模式 + Nacos 存储规则,这样规则也能版本化管理。
@Configuration
public class SentinelConfig {
@PostConstruct
public void initRules() {
// 从 Nacos 读取流控规则
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(
"localhost:8848", "prod", "user-service-flow-rules", source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {})
);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
}
真实事故:有一次大促,用户下单接口突然被打爆。Sentinel 自动触发了“慢调用比例熔断”,把非核心链路(比如发优惠券)直接降级,保住了主流程。事后复盘,运维老哥拍我肩膀:“小伙子,这次多亏了你搞的 Sentinel。”
第四步:K8s 集成 —— 让服务更云原生
因为我们全量跑在 K8s 上,所以做了几件事:
- 服务注册用 Pod IP:Nacos 客户端自动读取
POD_IP环境变量 - 健康检查对接 K8s livenessProbe:
livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 - 配置优先级:K8s ConfigMap > Nacos Config > application.yml(通过
spring.config.import控制)
最骚的是,我们还写了个小 工具,用 Go 写的 CLI,能一键从 Nacos 导出所有服务的依赖拓扑图,输出成 Graphviz 格式。运维老哥用来排查链路问题,直呼“内行”。
// 简化版伪代码
func ExportTopology(namespace string) {
services := nacosClient.ListServices(namespace)
for _, svc := range services {
instances := nacosClient.GetInstances(svc, namespace)
// 构建依赖关系...
}
// 输出 .dot 文件
}
性能对比:SCA vs Netflix
我们压测了两套架构(同规格 K8s 集群,4核8G Pod):
| 指标 | Eureka + Hystrix | Nacos + Sentinel |
|---|---|---|
| 服务注册延迟 | ~1.2s | ~300ms |
| 配置刷新延迟 | 需重启 | <1s(长轮询) |
| 限流精度 | 粗粒度(接口级) | 细粒度(参数级) |
| CPU 占用 | 较高(Hystrix 线程池开销) | 较低(Sentinel 基于滑动窗口) |
结论:SCA 在响应速度和资源消耗上明显优于 Netflix 套件,尤其适合高并发场景。
血泪教训 & 最佳实践
- 命名空间必须隔离:dev / test / prod 分开,别偷懒用 default。我们吃过亏,测试环境误删了生产配置。
- Sentinel 规则别硬编码:一定要持久化到 Nacos 或 Apollo,否则 Pod 重启规则就没了。
- Nacos 集群至少 3 节点:别信“单机够用”的鬼话,生产环境必须高可用。
- 监控不能少:集成 Prometheus + Grafana,监控 Nacos 注册数、Sentinel block 数。
- 别盲目上 Seata:分布式事务成本很高,先评估是否真的需要。我们最后用“本地消息表 + 幂等”解决了 90% 场景。
写在最后:离职前的“技术债清理”
其实这次迁移,除了技术升级,也是我给自己“清技术债”。在大厂两年,天天赶需求、修 Bug,很少有机会系统性重构。这次借着“国产化”东风,终于把那套老旧架构换掉了。
离职那天,Leader 请我喝了杯咖啡,说:“你走之前留的这套 SCA 架构,现在成了全公司微服务的标准模板。”
我笑了笑,心想:值了。
现在在家躺平,偶尔翻翻 GitHub 上 SCA 的 issue,看看社区新动态。也在学 Go,想着下份工作能不能试试云原生方向——毕竟 K8s 都玩这么熟了,总不能只用来部署 Java 吧?
如果你也在折腾 Spring Cloud Alibaba,欢迎留言交流。要是文章对你有帮助,不妨点个赞,或者去我 GitHub 点个 star(虽然还没放代码 😅)。
附:推荐学习路径
- 入门:官方文档 + 《Spring Cloud Alibaba 实战》
- 进阶:扒 Nacos/Sentinel 源码(GitHub 上都有)
- 工具链:Arthas(线上诊断)、SkyWalking(链路追踪)、Prometheus(监控)
记住:没有银弹,只有合适的方案。别为了用而用,先想清楚你的业务到底需要什么。
好了,我去泡面了。下次更新,可能是《从 Java 转 Go 的心路历程》,或者《如何优雅地拒绝无意义的需求》——敬请期待。

评论 0