触发条件一:错误率阈值

错误率阈值,说白了就是“失败多少次就拉闸”。

这是熔断降级最基础、也最常用的触发条件。你想想,一个服务不断报错,还继续放流量过去,那不是给用户喂屎吗?所以我们要定一个红线,一旦错误比例超过这个值,立刻打开熔断开关。

1.1 错误率怎么算?

先别急着定阈值,得把“错误率”的定义搞明白。在我接触过的项目里,最常见的方式是:

  • 错误次数 / 请求总数——简单直接,但容易被突发小流量带偏。比如1秒内就2个请求,1个失败,错误率50%,但其实样本太小,不具备代表性。
  • 滑动窗口内的错误率——比如统计最近10秒内的请求,或者最近1000个请求。这是工业界的标准做法。我习惯用时间窗口+最小请求量双重条件,避免“毛刺”误触发。

核心公式(以滑动窗口为例):

错误率 = 窗口内失败请求数 / 窗口内总请求数 × 100%

触发条件:错误率 >= 阈值(如 50%)
          且 窗口内总请求数 >= 最小请求量(如 10次)

为什么还要加最小请求量?我记得有一次线上排查,一个接口平时流量很小,某次健康检查刚好赶上重启,单个失败让错误率冲上100%,直接熔断了。后来加了“至少10个请求才统计”的约束,这种误判再没出现过。

1.2 滑动窗口的两种实现

我自己常用的是计数滑动窗口和时间桶滑动窗口。给你做个对比:

实现方式 思路 优势 劣势
计数滑动窗口 固定记录最近 N 次请求的状态 内存固定,实现简单 N 较小时容易丢失时间信息
时间桶滑动窗口 把时间切成小桶(如每1秒),统计每个桶内的成功/失败 能精准反映时间分布,抗突发 需要定期清理过期桶,内存稍大

曾经有个支付项目,用了计数滑动窗口,结果因为接口瞬时失败集中在1秒内,后面9秒又全是成功,错误率被稀释了。换成时间桶后,那1秒的失败率直接飙到80%,熔断立刻生效,避免了雪崩。这里要注意:时间粒度太粗会掩盖问题,太细则容易毛刺。我个人习惯用 10 秒窗口,桶大小 1 秒。

1.3 阈值怎么设?

没有一本书能告诉你“所有服务都设50%”。我的经验是分场景:

  • 关键核心链路(如下单、支付):阈值设低一点。我一般 20% ~ 30%。因为这些链路出问题直接影响收入,宁可错杀一千,不可放过一个。
  • 非核心查询接口:可以宽松到 50% ~ 70%。偶尔失败没关系,用户刷新一下就行。
  • 依赖外部第三方:第三方稳定性你没法控制。我习惯设 40% 左右,再配合超时熔断一起用。

小技巧:在生产环境可以先设一个“只告警不熔断”的观察期。比如阈值设成 30%,但熔断开关先不开启,只记录日志。观察一周,看看实际错误率分布,再微调阈值。我曾在三个项目里都是这么调的,一次都没踩坑。

1.4 错误分类:你真的该记它为失败吗?

嗯,这里要注意:不是所有异常响应都算“错误”。我们得区分:

  • 应计入错误的:HTTP 5xx、RPC 超时、线程池拒绝、业务异常(如库存不足但已经明确是服务端逻辑错误)。
  • 不应计入的:客户端参数错误(4xx)、请求被限流但限流属于主动保护不算错误、健康检查的单独探测。

我曾经犯过一个错:把所有业务异常都算进去了。结果因为某个接口经常返回“余额不足”的业务错误(其实是正常逻辑),错误率一直很高,熔断反复开关。后来把业务异常和系统异常分开统计,阈值只盯系统异常,总算清净了。

警告:如果熔断器把4xx也算作失败,用户随便发个恶意请求就能让整条链路熔断——这等于把熔断开关拱手让人。务必在统计层过滤干净。

1.5 什么时候恢复?

错误率阈值触发的熔断,恢复不是立刻重置错误计数器。我见过的典型策略:

  1. 半开试探:熔断后,经过一个冷却时间(如 5 秒),允许少量请求通过。如果这些请求全部成功,则关闭熔断;如果又有失败,则继续熔断。
  2. 滑动窗口清零:关闭熔断后,清空旧的错误计数窗口,重新统计。否则历史错误会持续影响新窗口。
  3. 恢复阈值:有时会设置一个“恢复错误率阈值”,比触发阈值更低。比如触发是 50%,恢复条件是最近 10 个请求错误率低于 20%。用恢复阈值能防止“边缘震荡”。

我记得一个社交 app 的推送服务,恢复了熔断后因为旧窗口还没过期,很快又触发熔断。加上“恢复时清空窗口”后,抖动减少很多。

1.6 流程图:错误率熔断决策

错误率阈值熔断决策流程 收到请求 熔断是否已打开? 是 否 半开:试探请求 或直通(冷却期后) 正常请求 统计滑动窗口 错误率 >= 阈值 ? 且请求数 >= 最小样本 是 否 打开熔断 继续放行 结束/进入冷却 要点: • 半开时只放少量请求 • 恢复条件可低于触发阈值 • 记得过滤掉不相关错误 • 窗口内最小样本量

1.7 避坑指南

最后聊几个我踩过的坑:

  • 阈值设得太死板:比如所有接口统一50%,结果有的接口正常错误率就40%,稍微抖动就误熔断。我后来改为按接口维度配置,在配置中心配成“/pay/order → 30%, /search/product → 60%”。
  • 忽略流量不均:某个接口白天流量大,错误率平稳;半夜流量小,一个失败就把错误率拉高。解决方法就是加最小请求量限制,比如“至少20个请求才统计”。
  • 恢复得太快:冷却时间设成1秒,结果半开试探又失败,又熔断,高频振荡。我建议冷却期至少5秒,试探请求数不超过总请求的1%。
  • 没有记录熔断原因:只记录“熔断”不记录“因错误率50%熔断”,事后排查时一脸懵。加上标签,比如 cause=error_rate, value=0.52,对定位非常有帮助。

一个小建议:如果团队刚引入熔断,先只对非核心接口生效。运行两周后观察误触率,再逐步铺开。别上来就给生产环境放“大杀器”,容易把自己玩崩。