从外包到甲方:我在 Spring Cloud Alibaba 生产环境踩过的那些坑
去年十月的一个周五晚上,我坐在南山区科技园某写字楼18楼的工位上,盯着屏幕上不断刷屏的 NacosConnectionException 日志,心里五味杂陈。窗外深圳湾的夜景依旧璀璨,但我却只觉得胃里一阵阵发紧。
那是我跳槽进这家甲方公司的第三周,月薪从外包时的15k涨到了22k,房租也从城中村的2000涨到了现在这套3500的小单间。老婆当时还开玩笑说:“终于不用吃泡面度日了。”可谁能想到,刚入职就碰上了微服务注册中心大规模失联的问题。
外包三年,终于上岸甲方
在写这篇分享之前,先简单介绍下我自己。我在深圳做了三年Java外包,辗转过两家公司,项目都是给银行、保险做内部系统维护。每天的工作就是改bug、加字段、写接口文档,技术栈停留在Spring Boot 2.1 + MyBatis,连Docker都只是听说过。
去年八月,在BOSS直聘上投了二十多份简历,终于收到了现在这家公司的面试邀请。面试官问了很多Spring Cloud Alibaba的问题,比如“Nacos和Eureka的区别”、“Sentinel怎么实现熔断降级”、“Seata的AT模式原理”。说实话,这些问题我在外包期间根本没接触过,只能凭着网上看的面试题临时抱佛脚。
但没想到,面试官最后说:“看你基础还行,虽然没实际用过SCA,但我们愿意培养。”那一刻,我真的差点在会议室哭出来。当天晚上回家就跟老婆商量:“要不咱们咬咬牙,搬去南山吧?通勤近,机会也多。”
第一个坑:Nacos集群配置翻车
入职后分配到的项目是一个电商中台系统,用了Spring Cloud Alibaba全家桶:Nacos做注册配置中心,Sentinel做限流熔断,Seata处理分布式事务。
第一个任务就是优化服务注册性能。原系统用的是Nacos单机部署,经常出现服务心跳超时。我信心满满地按照网上教程搭了个三节点集群,结果周一早上刚上线,整个测试环境就瘫了。
“怎么回事?所有服务都注册不上!”项目经理老张冲过来问我。
我手忙脚乱地查日志,发现是Nacos节点间的gRPC端口没开放。更尴尬的是,我在application.yml里把spring.cloud.nacos.discovery.server-addr配成了127.0.0.1:8848,而不是集群地址。
老张叹了口气:“小李啊,教程不能照搬啊。生产环境要考虑网络策略、安全组、负载均衡……”
那天加班到凌晨两点,才把集群重新配置好。但更大的问题还在后面。
第二个坑:配置中心的版本管理噩梦
解决了注册中心问题后,我又接到了配置管理的任务。原来的配置都是硬编码在properties文件里,每次改个超时时间都要重新打包部署。
我兴冲冲地把所有配置迁移到Nacos配置中心,还写了详细的使用文档。结果第二天测试就炸了——开发环境改了个数据库连接池大小,不小心同步到了生产环境。
“谁动了生产配置?!”运维同事在群里咆哮。
我赶紧去看Nacos控制台,发现根本没有配置版本回滚功能。当时的Nacos版本是2.0.3,还不支持配置的历史版本管理。这意味着一旦配错,只能手动恢复。
这次事故让我明白了一个道理:生产环境的每一个改动都要有回滚方案。后来我们升级到了Nacos 2.1+,配合Git来做配置版本管理,才算解决了这个问题。
第三个坑:Sentinel规则丢失之谜
最让我头疼的是Sentinel的问题。我们用Sentinel来做API限流,防止秒杀活动把系统打垮。本地测试一切正常,但每次重启应用,限流规则就全部消失了。
我翻遍了官方文档,才发现Sentinel默认的规则是内存存储的,应用重启就会丢失。要持久化规则,要么用Nacos做数据源,要么自己实现DataSource。
当时团队里没人做过这个,我只能硬着头皮研究。花了整整一周时间,才把限流规则持久化到Nacos,并且实现了动态刷新。
但问题又来了——规则太多的时候,Nacos推送会有延迟,导致某些服务实例没有及时收到最新的限流配置。这在高并发场景下简直是灾难。
最后我们采用了折中方案:核心接口的限流规则预加载到本地缓存,非核心接口走Nacos动态配置。虽然不够优雅,但至少保证了系统的稳定性。
第四个坑:Seata分布式事务的性能陷阱
项目里有个下单流程涉及三个服务:订单服务、库存服务、账户服务。最初我们直接用了Seata的AT模式,觉得这样最简单。
结果压测的时候发现,TPS从原来的800直接掉到了200。仔细分析才发现,Seata在每个SQL执行前后都要记录undo log,还要跟TC(Transaction Coordinator)频繁通信。
更糟糕的是,有一次MySQL主从切换,Seata的undo log表锁住了,导致整个下单流程完全不可用。
后来我们做了两件事:
- 对于非核心业务,改用最终一致性方案(消息队列+补偿机制)
- 核心业务保留Seata,但优化了数据库索引,减少了全局锁的持有时间
这个教训让我深刻理解了:没有银弹,只有合适的方案。
从踩坑到总结:给后来者的建议
回顾这几个月的经历,我觉得Spring Cloud Alibaba确实降低了微服务的门槛,但生产环境远比教程里写的复杂得多。
如果你也准备在生产环境使用SCA,我想分享几点血泪经验:
1. 不要迷信默认配置
Nacos、Sentinel、Seata的默认配置都是为了快速上手设计的,生产环境必须根据实际情况调整。比如Nacos的心跳间隔、Sentinel的滑动窗口大小、Seata的超时时间等。
2. 监控和告警必不可少
我们在踩了几次坑后,给所有SCA组件都加上了监控:
- Nacos的服务注册数、心跳成功率
- Sentinel的QPS、block次数
- Seata的全局事务成功率、回滚率
这些指标通过Prometheus + Grafana展示,一旦异常就钉钉告警。
3. 版本选择要谨慎
不要盲目追求最新版本。我们之前为了用新特性升级了Nacos,结果遇到了兼容性问题。现在我们的策略是:大版本稳定半年后再考虑升级。
4. 团队要有统一规范
比如配置命名规范、服务命名规范、Sentinel资源命名规范。否则人一多就乱套了。
5. 做好应急预案
每个组件都要有降级方案。比如Nacos挂了,能不能切回本地配置?Sentinel不可用,能不能关闭限流?
面试官常问的问题
说到这儿,我想起面试时被问到的几个经典面试题,现在有了实战经验,回答起来底气足多了:
Q:Nacos和Eureka有什么区别? A:以前我只会背“Nacos支持AP+CP,Eureka只支持AP”,现在我知道Nacos在生产环境中更容易运维,配置管理功能也更强大,但对网络要求更高。
Q:Sentinel怎么实现熔断降级? A:不再只是说“基于滑动窗口统计”,而是能结合实际场景说明:我们在订单查询接口设置了慢调用比例熔断,当响应时间超过2秒的比例超过50%时,自动熔断5分钟。
Q:Seata的AT模式有什么缺点? A:能具体说出性能损耗在哪里,以及什么场景不适合用AT模式。
写在最后
从外包到甲方,不仅仅是薪资的提升,更是责任的加重。在外包时,我只需要对自己写的代码负责;现在,我要对整个系统的稳定性负责。
上周五晚上,又是加班到很晚。但这次不是因为bug,而是主动优化系统架构。看着监控面板上平稳的各项指标,突然觉得这几个月的辛苦都值得了。
深圳的房价还是那么高,南山的房租依然让人肉疼,但至少我现在做的工作是有技术含量的,是在真正解决问题,而不是重复劳动。
如果你也在外包,想要跳槽到甲方,我的建议是:不要只刷面试题,要真正动手实践。哪怕是在自己的电脑上搭一套完整的SCA环境,也比死记硬背强。
技术这条路很难,但每踩一个坑,都是在为自己的未来铺路。希望我的这些踩坑经历,能帮你在Spring Cloud Alibaba的生产实践中少走一些弯路。
共勉。

评论 0