首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >滚动发布疯狂报 RPC 异常!藏 3 年的 Spring Cloud 祖传大坑,90% Nacos 集群全部踩中

滚动发布疯狂报 RPC 异常!藏 3 年的 Spring Cloud 祖传大坑,90% Nacos 集群全部踩中

作者头像
用户12591013
发布2026-07-10 15:56:22
发布2026-07-10 15:56:22
1250
举报

你以为做了优雅下线就万无一失?Spring Cloud LoadBalancer 的默认缓存,才是发布期报错的真凶!


一、诡异的线上故障

我们用 K8s+Nacos 做了一套 “完美” 的滚动发布流程:

  • 先启动新 Pod,健康检查通过后再销毁旧 Pod
  • 旧 Pod 销毁前主动调用 Nacos 接口摘除自己
  • 预期:调用方实时感知实例下线,RPC 报错趋近于 0

结果:每次发版都有数十秒的 RPC 超时 / 连接失败,报错峰值持续 30 + 秒,Nacos 控制台已经看不到旧实例,但流量还在往已销毁的 Pod 上打。


二、根因定位:35 秒缓存拦死了实时感知

1. 元凶配置

代码语言:javascript
复制
spring:
 cloud:
   loadbalancer:
     cache:
       enabled:true # 默认开启!全公司没人改

2. 源码实锤:默认 35 秒 TTL

从 Spring Cloud LoadBalancer 源码可以直接看到,缓存 TTL 被硬编码为35 秒

注释:Time To Live - 从写入开始计算,35 秒后缓存过期。

3. 底层逻辑

Spring Cloud LoadBalancer 会缓存服务实例列表,35 秒内不会主动刷新:

1. 每次 RPC 负载均衡,优先读本地缓存

2. Nacos 2.x 虽然用 gRPC 实时推送实例变更,但清不掉这层缓存

3. 旧实例下线后,调用方还要拿着 35 秒前的旧列表继续发流量


三、历史坑:为兼容 Eureka,坑了 Nacos

1. 缓存的诞生(Eureka 时代)

早期 Eureka Client 是HTTP 定时轮询拉取服务列表(默认 30 秒一次),网络开销大。LoadBalancer 缓存是为了:

  • 减少对注册中心的 HTTP 请求
  • 提升性能,避免每次调用都拉取

2. Nacos 2.x 时代,缓存彻底冗余

Nacos 2.x 改用gRPC 长连接 + 实时推送:

  • 服务上下线,毫秒级推送给所有消费端
  • Nacos Client 内存里维护着最新实例列表,根本不需要再缓存

但 Spring Cloud 为了兼容所有注册中心,不能为 Nacos 单独去掉缓存,于是这个 “历史包袱” 就成了 Nacos 用户的大坑。


四、根治方案:一行配置彻底解决

1. 推荐配置(直接复制)

代码语言:javascript
复制
spring:
 cloud:
   loadbalancer:
     cache:
       enabled:false

2. 效果

  • 每次负载均衡直接读 Nacos Client 的实时实例列表
  • 实例下线后,流量瞬间不再路由到旧节点
  • 发布期 RPC 报错率直接降到接近 0

3. 性能顾虑?

Nacos Client 本身已经在内存里维护了最新实例,调用getInstances是纯内存操作,没有网络 IO,关闭缓存不会增加注册中心压力。


五、折中方案(不推荐)

如果暂时不能关闭缓存,可以缩短 TTL,但治标不治本:

代码语言:javascript
复制
spring:
 cloud:
   loadbalancer:
     cache:
       enabled:true
       ttl: 5s # 缩短到5秒,减少报错窗口

六、避坑总结

  • Nacos 2.x 必须关闭 LoadBalancer 缓存:cache.enabled=false
  • 不要无脑用框架默认配置,要结合中间件底层原理判断
  • 滚动发布、灰度、扩缩容场景,缓存是实时感知的最大敌人
  • 框架的 “通用兼容” 设计,往往是特定场景下的性能陷阱

文末小结

很多线上长期疑难问题,都不是业务 Bug,而是框架为了兼容历史组件留下的 “设计债务”。只会复制粘贴配置的 CRUD 工程师,永远发现不了这种藏了 3 年的坑;只有吃透底层通信原理,才能真正做到零故障发布。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鹏哥调优笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、诡异的线上故障
  • 二、根因定位:35 秒缓存拦死了实时感知
    • 1. 元凶配置
    • 2. 源码实锤:默认 35 秒 TTL
    • 3. 底层逻辑
  • 三、历史坑:为兼容 Eureka,坑了 Nacos
    • 1. 缓存的诞生(Eureka 时代)
    • 2. Nacos 2.x 时代,缓存彻底冗余
  • 四、根治方案:一行配置彻底解决
    • 1. 推荐配置(直接复制)
    • 2. 效果
    • 3. 性能顾虑?
  • 五、折中方案(不推荐)
  • 六、避坑总结
  • 文末小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档