熔断是直接拒绝调用,降级是调用失败后返回兜底值;判断依据为:Redis彻底不可用触发熔断,响应变慢或部分key失效则走降级,数据库超载时降级须配合限流。

服务降级和熔断不是“开了就万事大吉”的开关,而是需要按数据重要性分级、blockHandler 不能返回 null、且必须配合监控指标触发——否则可能把雪崩变成系统瘫痪。
怎么判断该走降级还是熔断?看请求来源和数据等级
降级和熔断常被混用,但实际行为完全不同:熔断是直接拒绝所有缓存调用(redisTemplate.opsForValue().get(key) 不发请求),降级是允许调用,但失败后返回兜底值。选哪个取决于两点:
- Redis 是否彻底不可用(如进程宕机、网络中断)→ 触发
HystrixCommand或@SentinelResource的熔断,跳过 Redis 调用 - Redis 响应变慢或部分 key 失效(如大量 key 同时过期)→ 用降级,保留核心路径(如库存查询仍走 DB),非核心路径(如商品描述)返回
"暂无详情" - 数据库负载是否已超阈值(如 CPU >90% 或慢 SQL 数 >50/min)→ 此时降级必须配合限流,否则兜底逻辑本身会压垮 DB
@SentinelResource 的 blockHandler 为什么不能只 return null?
很多团队在 blockHandler 里写 return null,结果上游 service 解包时抛 NullPointerException,引发连锁失败。这不是降级,是甩锅。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 返回值类型必须与原方法一致,且需保证下游能安全消费:字符串字段返回
"",对象字段返回空对象(如new User().setUsername("未知用户")),集合字段返回Collections.emptyList() - 不要在
blockHandler里再查 DB 或调其他远程服务——它本就是“快速失败”环节,耗时应 - 记录日志时带上
originKey和触发原因(如"redis timeout, fallback to default"),否则无法区分是雪崩还是单点故障
Hystrix 熔断配置容易忽略的三个硬参数
Hystrix 默认配置对缓存雪崩场景基本无效,必须手动调:
-
execution.timeoutInMilliseconds设为 800ms(不是默认 1000ms):Redis 响应超过 800ms 已属异常,继续等只会堆积线程 -
circuitBreaker.errorThresholdPercentage从 50% 改为 30%:缓存雪崩初期错误率飙升极快,等错一半才熔断太晚 -
metrics.rollingStats.timeInMilliseconds缩短到 10000(10 秒窗口):长窗口(如默认 10 分钟)会导致熔断滞后,错过黄金处置时间
Redis 宕机时,熔断状态如何自动恢复?
熔断器不会自己“感知 Redis 恢复”,必须靠主动探测 + 状态重置:
- 单独起一个健康检查线程,每 2 秒 ping 一次 Redis(
redisTemplate.getConnectionFactory().getConnection().ping()),连续 3 次成功才标记为“可恢复” - 调用
HystrixCommand.reset()或 Sentinel 的ClusterStateManager.updateState(ClusterStateManager.ClusterState.OK),否则熔断状态会卡死 - 恢复初期要加“半开”保护:只放行 5% 流量,全部成功后再逐步放开,避免 Redis 刚起来又被打挂
最常被漏掉的是降级/熔断后的监控闭环——没告警、没 trace、没流量对比图,等于开着盲盒跑生产。雪崩不是技术问题,是可观测性缺失的后果。

















