resilience4j默认不支持分布式熔断,其circuitbreaker状态仅存在于jvm内存中;若需多实例共享熔断状态,须手动通过redis存储并同步状态,如监听onstatetransitionevent写入、调用前读取覆盖本地状态,同时做好缓存、降级兜底与并发控制。

Resilience4j 本身不依赖 Redis,也不能直接用 Redis 实现熔断;但你可以用 Redis 做两件事:存储熔断器状态(跨实例共享)、或作为降级逻辑的数据源——前提是自己编码桥接,官方不内置。
Resilience4j 的 CircuitBreaker 默认是进程内状态
它的 CircuitBreaker 状态机(CLOSED / OPEN / HALF_OPEN)默认只存在 JVM 内存里。这意味着:如果你有 3 个 order-service 实例,每个实例的熔断开关独立判断、独立切换——A 实例把 user-service 熔断了,B 实例可能还在疯狂重试,雪崩风险仍在。
常见错误现象:
压测时单实例熔断生效,上线后多实例下故障服务仍被高频调用,监控看到失败率居高不下,误以为配置没起作用。
- Resilience4j 不提供开箱即用的分布式熔断能力,
CircuitBreakerRegistry是本地单例 - 若需集群级熔断决策,必须自己把状态同步出去——Redis 是最常用选择,但要手写状态读写逻辑
- 注意:不要试图用 Redis 的过期键模拟熔断器,
OPEN状态需要精确计时 + 半开试探 + 失败率滑动窗口,纯 Redis 键值无法承载
用 Redis 存储并同步 CircuitBreaker 状态的关键点
核心思路是:拦截 CircuitBreaker 状态变更事件(OnStateTransitionEvent),将当前状态、最后更新时间、滑动窗口统计等序列化后写入 Redis;同时在每次调用前,从 Redis 拉取最新状态覆盖本地实例的状态缓存。
使用场景:
多节点部署的订单服务,需统一感知用户服务的可用性,避免部分实例“带病上岗”。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 必须监听
CircuitBreakerOnStateTransitionEvent,在onEvent回调中调用redisTemplate.opsForValue().set()写入状态,key 建议为circuitbreaker:order-service:user-service:state - 读取时机很关键:不能只在启动时加载一次,要在每次
canCallApi()前通过redisTemplate.opsForValue().get()获取,并用CircuitBreaker.transitionTo...强制同步到本地状态机 - 性能影响:每次调用都查 Redis 会拖慢吞吐,建议加本地 LRU 缓存(如
ConcurrentHashMap+ 定时刷新),TTL 控制在 1–3 秒内 - 注意 Redis 连接超时和连接池耗尽问题,降级逻辑里必须兜底——查不到 Redis 状态时,默认走本地熔断器,不能抛异常
Redis 更适合做降级数据源,而非熔断控制器
比起硬刚分布式熔断状态同步,把 Redis 当作降级兜底的数据源更自然、更稳定。例如:当 user-service 熔断后,降级方法 fallbackGetUser() 不返回空对象,而是从 Redis 读取最近缓存的用户快照(user:1001:cache)返回。
参数差异:
这类降级不依赖 Resilience4j 的任何新配置,只需确保你的 @Fallback 方法里能正常注入 RedisTemplate。
- 缓存快照需定期更新(如用户信息变更时触发
SET user:1001:cache ... EX 300),不能依赖被动过期 - 避免缓存穿透:降级逻辑中对不存在的
userId,也要写空值(SET user:9999:cache NULL EX 60),否则反复击穿 - 注意 Redis 雪崩风险:如果所有降级 key 都设相同 TTL,可能集体失效引发 DB 打满——务必加随机偏移,如
EX 300 + ThreadLocalRandom.current().nextInt(60)
别忽略 Resilience4j 和 Redis 的协作边界
最容易被忽略的是:Resilience4j 的 TimeLimiter 和 RateLimiter 也都不连 Redis。如果你用 RateLimiter 做接口限流,它仍是单机 QPS 控制;想做分布式限流,得换 Sentinel 或自己基于 Redis Lua 脚本实现令牌桶。
复杂点在于:熔断、降级、限流、超时这四层防护,Resilience4j 只负责前三个的本地逻辑,Redis 只是你的数据管道或备用仓库,两者之间没有自动粘合。任何跨进程协调,都得你定义清楚状态结构、序列化方式、竞争处理(比如用 Redis 的 SETNX 配合过期时间防脑裂)。










