裸辞半年后,我在出租屋里重构微服务:一个前大厂后端的 Spring Cloud Alibaba 实战手记

林芳
2025-12-26 16:56
阅读 365

上周五晚上十一点,北京五环外一间月租3500的单间里,我正对着屏幕上一串诡异的 Nacos 配置中心报错发愣。窗外滴滴打车的提示音此起彼伏,而我的手机突然震动——是老婆发来的消息:“今天面试怎么样?”

我苦笑了一下,回了个“还在调配置”,然后默默关掉 IDE,点了份28块钱的黄焖鸡。这是裸辞后的第172天,也是我重新找工作以来的第9次技术面。曾经在某一线大厂带3人小团队、月薪22k的“资深后端工程师”,如今却在出租屋里一边啃鸡腿一边调试一个连测试环境都跑不起来的 Demo。

一、为什么我会在这里?

时间倒回去年十月。那时我还在深圳,和老婆异地一年半。她在上海做运营,我在深圳搞后端,每周五晚高铁、周日晚返程成了固定节奏。那天凌晨两点,我在公司改完一个紧急上线的 Spring Cloud Gateway 网关限流策略,看着工位上那盆枯死的绿萝,突然意识到:我已经连续三个月没陪她吃过一顿完整的饭了

第二天早上,我和老婆视频。她眼睛有点红,说:“要不……你先休息一段时间?”
我说:“可我还背着房贷。”
她说:“我们还有点存款,撑半年应该没问题。”

于是,我裸辞了。HR 谈离职时还开玩笑:“你可是我们组第一个主动走的,别后悔啊。”
我当时心里想的是:“老子再也不想半夜被 PagerDuty 叫醒了。”

但现实很快打了脸。Gap 的前三个月还算惬意:看书、健身、学点 Python 做点小工具。可到了第四个月,简历投出去石沉大海;第五个月,开始焦虑得睡不着觉;第六个月,我甚至怀疑自己是不是已经“技术过时”了。

直到上个月,一家中型电商公司给了个终面机会,岗位要求明确写着:“熟悉 Spring Cloud Alibaba 生产实践”。我翻出尘封已久的 IDEA,决定用一周时间,从零搭一套“能跑生产”的微服务架构——不是玩具 Demo,而是真正考虑高可用、可观测性、灰度发布这些实际问题的系统。

二、从“Hello World”到生产级:Spring Cloud Alibaba 的真实挑战

很多人以为 Spring Cloud Alibaba(以下简称 SCA)就是把 Eureka 换成 Nacos、Hystrix 换 Sentinel 这么简单。但真到生产环境,坑多得像我老婆吐槽我袜子乱扔一样密集。

场景一:Nacos 配置中心的“幽灵更新”

我一开始直接用了 Nacos 的 @RefreshScope + @Value 注解组合。本地跑得好好的,结果部署到测试环境后,配置改了,服务却没生效。查了半天日志,才发现 Nacos 客户端默认使用长轮询拉取配置,但某些网络环境下会退化为短轮询,导致延迟高达30秒

更致命的是,有一次我把数据库密码改错了,结果服务启动时读的是旧配置(因为启动时还没连接上 Nacos),直接连不上 DB,整个服务挂了。那一刻我差点砸键盘。

解决方案

  • 启动时强制从 Nacos 拉取最新配置(通过 ConfigService.getConfig() 手动加载)
  • 对敏感配置(如 DB 密码)加校验逻辑,启动失败直接 exit -1
  • 配合 Apollo 的“配置快照”思路,在本地 cache 一份 fallback 配置

这让我想起在大厂时,运维同事总说:“配置中心不是银弹,它只是把‘改代码重启’变成了‘改配置热更新’,但错误的成本一点没降。”

场景二:Sentinel 的“假熔断”

为了模拟生产流量,我用 Python 写了个简易压测脚本(毕竟老婆老说我只会 Java,得证明下自己也会 Python):

import requests
import time
from concurrent.futures import ThreadPoolExecutor

def send_request():
    try:
        resp = requests.get("http://localhost:8080/order/create", timeout=2)
        print(f"Status: {resp.status_code}")
    except:
        print("Timeout!")

with ThreadPoolExecutor(max_workers=50) as executor:
    for _ in range(1000):
        executor.submit(send_request)
        time.sleep(0.01)

结果发现,当 QPS 超过 200 时,Sentinel 熔断规则明明触发了,但接口还是返回 500,而不是我预设的 fallback 响应。查源码才发现:Sentinel 默认只对 BlockException 做处理,而我的业务异常(比如空指针)根本不会触发熔断逻辑

这就像你给家门装了智能锁,结果小偷是从窗户爬进来的——防护机制完全没覆盖到真实风险点。

改进做法

  • 在 Controller 层统一捕获异常,区分业务异常和系统异常
  • 对关键方法手动包装 try-catch,显式调用 SphU.entry()
  • 结合 OpenFeign 使用时,务必开启 fallbackFactory,否则远程调用超时也不会触发降级

场景三:Seata 的“分布式事务幻觉”

最头疼的是分布式事务。我用 Seata 的 AT 模式处理“下单扣库存”场景。本地测试完美回滚,但一上 Kubernetes 集群,就出现“库存扣了但订单没创建”的脏数据。

后来发现是 Seata Server(TC)和客户端(TM/RM)之间的网络分区问题。当 Pod 重启时,Seata Client 重连 TC 失败,但本地事务已经提交,全局事务状态丢失。

这个问题让我彻夜难眠。凌晨三点,我给前同事发微信:“你们当年是怎么保证 Seata 高可用的?” 他回得很快:“我们压根没用 AT 模式,全靠消息队列+本地事务表+定时对账。”

那一刻我醍醐灌顶:技术选型不是“哪个新就用哪个”,而是“哪个稳就用哪个”。在大厂,我们有专职中间件团队兜底;但在中小公司,你可能就是那个“兜底的人”。

三、Python 不是主角,但它是我的“瑞士军刀”

很多人看到技术文章标题带 “Python”,以为我要讲微服务用 Python 写。其实恰恰相反——我的核心服务全是 Java + SCA,但 Python 成了我提升效率的利器。

比如:

  • locust 写分布式压测脚本,比 JMeter 脚本简洁十倍
  • pandas 分析 Nacos 配置变更历史,找出频繁修改的“高危配置项”
  • flask 快速搭个内部工具,把 Sentinel 规则可视化(毕竟官方 dashboard 太简陋)

甚至这次面试准备,我也用 Python 写了个小工具,自动从 GitHub 抓取 SCA 最新 issue,过滤出 “production”、“bug” 关键词,提前了解社区痛点。

老婆笑我说:“你这不是后端,是 DevOps + SRE + 工具人。”
我回她:“在小公司,你不全能,就得滚蛋。”

四、从“架构师思维”到“生存者思维”

在大厂时,我们讨论的是“如何设计百万 QPS 的网关”,现在我关心的是“如何用最低成本让服务别挂”。这种转变起初让我很不适,总觉得“格局小了”。但 Gap 半年让我明白:所有脱离业务场景谈架构的,都是耍流氓

举个例子:

  • 大厂方案:Nacos 集群三节点 + MySQL 主从 + VIP 漂移
  • 我现在的方案:Nacos 单机 + Docker Compose + 阿里云 NAS 挂载配置目录

后者当然不够“高大上”,但它满足三个条件:

  1. 成本低于 200 元/月
  2. 我一个人能维护
  3. 能支撑当前业务量(日活 < 1万)

真正的架构能力,不是堆砌技术名词,而是在约束条件下做出最优权衡。就像我和老婆商量裸辞时说的:“我们不是追求完美生活,而是找到当下最可持续的状态。”

五、面试官问:“你最大的收获是什么?”

今天下午的终面,技术总监最后问我这个问题。我没有背八股文,而是说了这段经历。

我说:“以前我觉得 Spring Cloud Alibaba 是一套技术组件,现在我知道它是一套协作契约。Nacos 统一了配置语言,Sentinel 定义了容错边界,Seata 约定了事务语义——它们让不同团队、不同服务能在一个共同规则下安全交互。”

“而作为一个经历过裸辞焦虑的人,我更懂得:技术的价值不在于多酷炫,而在于能不能让业务活下去,让团队少加班,让老婆少担心。”

他笑了笑,说:“下周来入职吧,base 20k,给你配两个实习生。”

走出写字楼,北京的春天终于有了点暖意。我给老婆发了条语音:“工作找到了,下个月搬去上海,结束异地。”
她沉默了几秒,然后笑着说:“那你得先学会用 Python 写个自动化脚本,帮我整理运营数据。”

六、写在最后:给同样迷茫的你

如果你也在 Gap,也在焦虑技术是否过时,也在深夜 debug 到崩溃——我想说:你的价值,从不取决于你用了多少个“热门框架”

Spring Cloud Alibaba 很好,但它的核心思想——服务发现、配置管理、流量治理、分布式事务——早在它出现前就存在。技术会变,但解决问题的思维不变。

这半年,我失去了稳定的收入,但也找回了对技术的敬畏。我不再盲目追新,而是学会问:“这个方案,真的适合我的业务吗?我能 hold 住它的所有 edge case 吗?”

回到文章开头的那个夜晚,其实我没告诉老婆全部真相。当时 Nacos 报错是因为我把 namespace 写错了,一个低级到羞于启齿的错误。但正是这些“低级错误”,让我明白:再牛的架构,也抵不过一次粗心的配置

所以,别怕裸辞,别怕 Gap,别怕从头开始。只要还在敲代码,还在思考,你就没掉队。

只是下次,记得把 namespace 写对。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝