LoadBalancer 缓存配置方案
问题场景
当服务从注册中心(如 Nacos)注销后,客户端仍然会继续调用已下线的服务实例,导致请求失败。
时间线示例:

14:34:04 service-provider 从 Nacos 注销服务 14:34:15 service-consumer 服务还在调用已注销的服务,报错
错误信息:

feign.RetryableException: No route to host (Host unreachable) executing GET http://service-provider/api/health Caused by: java.net.NoRouteToHostException: No route to host (Host unreachable)
根本原因
Spring Cloud LoadBalancer 会缓存服务实例列表,默认缓存时间(TTL)为 35 秒。
工作流程:

1. 首次获取服务实例列表 → 写入缓存 2. 35 秒内 → 使用缓存的实例列表(不会查询注册中心) 3. 35 秒后 → 缓存过期,重新从注册中心获取
问题根源:

服务下线时间点:T0 ├─ Nacos 注册中心:服务已注销 ✅ ├─ LoadBalancer 缓存:还有 20+ 秒才过期 ❌ └─ 客户端:继续使用缓存中的旧实例列表 ❌ ↓ 结果:调用已下线的服务 → 连接失败 → 超时异常
解决方案
配置 LoadBalancer 缓存时间
在 bootstrap.yml 或 application.yml 中配置:

spring: cloud: loadbalancer: cache: ttl: 35s # 缓存过期时间,默认 35 秒 capacity: 256 # 缓存容量,默认 256
配置说明
1. ttl(Time To Live)
-
作用:控制服务实例列表在本地缓存中的存活时间
-
默认值 :
35s(35 秒) -
单位:支持秒(s)、分钟(m)、小时(h)等
-
工作流程 :

首次获取 → 写入缓存 → ttl 时间内使用缓存 → ttl 后重新获取
2. capacity
- 作用:设置缓存容量(最多缓存多少个服务的实例列表)
- 默认值 :
256 - 说明:一般不需要修改
配置示例
示例 1:快速感知服务变化(开发/测试环境)

spring: cloud: loadbalancer: cache: ttl: 5s # 5 秒后刷新缓存,快速感知服务变化
适用场景:
- 开发环境
- 测试环境
- 需要快速感知服务变化的场景
优点:
- 快速感知服务变化
- 服务下线后最多 5 秒就能感知到
缺点:
- 增加注册中心查询压力
- 可能影响性能(频繁查询)
示例 2:平衡性能和实时性(生产环境推荐)

spring: cloud: loadbalancer: cache: ttl: 35s # 默认值,平衡性能和实时性
适用场景:
- 生产环境
- 服务实例变化不频繁的场景
优点:
- 减少注册中心查询压力
- 性能友好
- 35 秒的延迟通常可接受
缺点:
- 服务下线后最多 35 秒才能感知到
示例 3:禁用缓存(不推荐)

spring: cloud: loadbalancer: cache: ttl: 0s # 禁用缓存,每次都查询注册中心
适用场景:
- 调试场景
- 服务实例频繁变化的场景
优点:
- 实时性最高
- 立即感知服务变化
缺点:
- 性能影响大(每次调用都查询注册中心)
- 增加注册中心压力
- 不适用于生产环境
配置建议
根据环境选择
| 环境 | 推荐 ttl | 说明 |
|---|---|---|
| 开发环境 | 5s - 10s |
快速感知变化,便于调试 |
| 测试环境 | 10s - 20s |
平衡性能和实时性 |
| 生产环境 | 35s(默认) |
性能优先,减少注册中心压力 |
根据业务场景选择
| 场景 | 推荐 ttl | 说明 |
|---|---|---|
| 服务实例稳定 | 35s - 60s |
实例变化少,可以设置较长缓存时间 |
| 服务实例频繁变化 | 10s - 20s |
需要快速感知变化 |
| 高并发场景 | 35s - 60s |
减少查询压力,提升性能 |
| 低延迟要求 | 5s - 10s |
需要快速感知服务变化 |
注意事项
1. 缓存时间与优雅下线
如果使用优雅下线方案,需要确保:

优雅下线等待时间 ≥ LoadBalancer 缓存 ttl + 缓冲时间(5-10秒)
示例:

# LoadBalancer 配置 spring: cloud: loadbalancer: cache: ttl: 35s # 优雅下线配置(preStop Hook 或 @PreDestroy) sleep_time = 35s + 5s = 40s # 至少等待 40 秒
2. 缓存时间不宜过短
- 过短 (如
1s):频繁查询注册中心,影响性能 - 适中 (如
10s-35s):平衡性能和实时性 - 过长 (如
300s):服务变化感知延迟大
3. 监控缓存效果
建议监控以下指标:
- 缓存命中率
- 注册中心查询频率
- 服务发现延迟
完整配置示例
生产环境配置

spring: cloud: loadbalancer: cache: ttl: 35s # 缓存过期时间:35 秒 capacity: 256 # 缓存容量:256
开发环境配置

spring: cloud: loadbalancer: cache: ttl: 5s # 缓存过期时间:5 秒(快速感知变化) capacity: 256 # 缓存容量:256
验证方法
1. 查看日志
配置后,可以通过日志观察服务实例列表的刷新:

# 首次获取服务实例 [INFO] 已知的被调用方服务地址: 192.168.1.100:8080, 192.168.1.101:8080 # 服务下线后,等待 ttl 时间... # 缓存过期后,重新获取(已下线的服务不再出现) [INFO] 已知的被调用方服务地址: 192.168.1.101:8080
2. 测试服务下线
- 启动两个服务实例
- 观察客户端日志,确认能看到两个实例
- 下线一个服务实例
- 观察客户端日志,确认在
ttl时间后,下线的实例不再出现
总结
核心要点
- LoadBalancer 缓存机制:默认缓存 35 秒,减少注册中心查询压力
- 配置位置 :
spring.cloud.loadbalancer.cache.ttl - 推荐值 :
- 生产环境:
35s(默认值) - 开发/测试环境:
5s-10s
- 生产环境:
- 注意事项 :如果使用优雅下线,需要确保等待时间 ≥
ttl + 缓冲时间
最佳实践
- ✅ 生产环境使用默认值
35s - ✅ 开发/测试环境可以缩短到
5s-10s - ✅ 配合优雅下线方案使用
- ✅ 监控缓存效果和注册中心压力
- ❌ 避免设置过短的缓存时间(< 3秒)
- ❌ 避免在生产环境禁用缓存(
ttl: 0)