降级开关必须放在应用层,是应用代码中可动态控制的布尔标记,推荐用本地内存变量+配置中心驱动,覆盖完整缓存链路,分场景返回业务语义兜底值,并与熔断器解耦联动。

降级开关必须放在应用层,不能依赖 Redis 自身
Redis 本身没有“降级开关”这个概念,CONFIG SET 或 redis-cli shutdown 这类操作不是降级,是停服。真正的降级开关是应用代码里一个可动态控制的布尔标记或配置项,它决定是否跳过缓存、直连 DB 或返回兜底值。
常见错误是把 spring.redis.enabled=false 当作降级开关——这会直接断掉所有 Redis 操作,连健康检查都失败,反而触发更激进的熔断;或者用 SET cache_switch 0 然后每次查 key 前 GET cache_switch,既增加 RT 又引入单点依赖。
- 推荐做法:用本地内存变量 + 配置中心驱动,比如 Spring Cloud Config 或 Apollo 中定义
cache.fallback.enabled=true,应用监听变更并更新一个AtomicBoolean fallbackSwitch - 不要在每次请求中远程读取开关状态;开关变更频率低(分钟级),本地缓存 30 秒足够
- 开关生效要覆盖完整链路:不只是
get()跳过 Redis,set()也应静默丢弃,避免脏写
降级策略要分场景,不能一刀切返回 null
直接 return null 或抛 CacheUnavailableException 是最危险的降级——下游服务可能 NPE,前端渲染崩溃。降级必须匹配业务语义。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 用户信息查询失败 → 返回
User.anonymous(),头像/昵称用默认值,不中断登录流程 - 商品价格查不到 → 返回历史价格(从本地缓存或 DB 冗余字段读),而非 0 元或空
- 订单列表不可用 → 返回最近 3 条本地缓存数据 + “数据加载中”提示,保持 UI 可交互
- 开关开启时,日志必须打标
fallback=price_service,方便快速定位影响范围
开关与熔断器必须解耦,但状态要联动
降级开关是人工干预入口,熔断器是自动响应机制,二者不能互相替代,但需要协同。比如 DB 熔断器进入 OPEN 状态时,自动把降级开关设为 true;而人工关闭开关时,不应强行重置熔断器计数器。
- Resilience4j 的
CircuitBreaker状态变更事件可以监听:circuitBreaker.onStateTransition(state -> { if (state == OPEN) enableFallback(); }) - 人工开关关闭后,需等待熔断器自然进入
HALF_OPEN才恢复缓存,不能立即切回 - 避免循环:不要在 fallback 逻辑里再调一次带熔断的 DB 方法,否则会卡死在降级态
开关的灰度和回滚成本常被低估
线上开降级开关不是按个按钮就完事。真实系统里,一个开关背后往往关联多个服务、多种数据类型、不同客户端版本。
- 先按流量比例灰度:用
userId % 100 控制 5% 用户走降级,观察 error rate 和 DB load - 开关打开后,Redis 连接池不能立刻释放——要等活跃连接自然超时,否则残留连接可能触发
Connection refused - 回滚时最易出错:DB 刚恢复,缓存还没重建,大量请求击穿 → 必须配合预热脚本或空值缓存 TTL 延长

















