什么是熔断?

#中间件#面试八股

什么是熔断?

结论:熔断(Circuit Breaker)是当下游依赖的错误率或慢调用比例超过阈值时,主动切断对该依赖的调用,快速失败或走降级逻辑,避免调用方线程被慢请求耗尽、故障沿链路扩散。它有三个状态:关闭(CLOSED)、打开(OPEN)、半开(HALF_OPEN)。

一、三态状态机

               错误率或慢调用比例超阈值
      ┌────────┐ ──────────────────────► ┌────────┐
      │ CLOSED │                         │  OPEN  │
      │ 正常放行│ ◄────────────────────── │ 直接失败│
      └────────┘    半开探测成功           └───┬────┘
           ▲                                  │ 等待窗口结束
           │           ┌───────────┐          │
           └───────────│ HALF_OPEN │ ◄────────┘
             探测成功   │ 放行少量   │
                       └─────┬─────┘
                             │ 探测失败
                             ▼
                    回到 OPEN,窗口可翻倍
  • CLOSED:正常调用,同时用滑动窗口统计成功率与慢调用比例。
  • OPEN:直接拒绝,不再发起真实调用,通常配合降级(Fallback)返回兜底值。
  • HALF_OPEN:窗口结束后放行少量探测请求,成功则恢复,失败则继续熔断。

二、触发条件

指标含义典型阈值
慢调用比例RT 超过阈值的请求占比50%,RT 阈值 800 ms
异常比例异常请求占比50%
异常数窗口内异常绝对数量10 次 / 10 秒
最小请求数统计样本下限20 次,避免样本太少误判

滑动窗口(Sliding Window)通常按秒分桶,统计最近 N 秒;窗口越大越平滑,但也越迟钝。

三、配置:Sentinel 与 Resilience4j

# Sentinel 熔断规则
[
  {
    "resource": "queryOrderFromPay",
    "grade": 1,                  # 0=慢调用比例 1=异常比例 2=异常数
    "count": 0.5,
    "slowRatioThreshold": 0.5,
    "timeWindow": 10,
    "minRequestAmount": 20,
    "statIntervalMs": 10000
  }
]
# Resilience4j
resilience4j:
  circuitbreaker:
    instances:
      payClient:
        sliding-window-type: COUNT_BASED
        sliding-window-size: 50
        failure-rate-threshold: 50
        slow-call-duration-threshold: 800ms
        slow-call-rate-threshold: 60
        wait-duration-in-open-state: 10s
        permitted-number-of-calls-in-half-open-state: 3

四、熔断必须配降级

@SentinelResource(value = "queryPayStatus", fallback = "payStatusFallback")
public PayStatus queryPayStatus(String orderNo) {
    return payClient.query(orderNo);
}

// 熔断或异常时走这里:返回「处理中」,让前端轮询,而不是直接报错
public PayStatus payStatusFallback(String orderNo, Throwable t) {
    log.warn("支付状态查询降级 orderNo={} cause={}", orderNo, t.toString());
    return PayStatus.PROCESSING;
}

没有 fallback 的熔断,只是把「慢失败」变成「快失败」,用户体验未必更好。

五、常见追问

Q1:熔断和限流有什么区别? 限流控制进入系统的流量,按 QPS 或并发数拒绝;熔断控制对某个依赖的调用,依据错误率与 RT,属于对故障的被动响应。

Q2:半开状态为什么只放少量请求? 探测期若放全量,故障未恢复会立刻再次打崩下游;只放 1 到 3 个请求,成本可控,又能验证依赖是否恢复。

Q3:熔断阈值怎么定? 基于 SLO 反推:允许的失败率是多少、下游恢复需要多久。阈值太低会误熔断,正常抖动也断开;太高则失去保护意义。通常从 50% 与 10 秒窗口起步,再按压测调整。

Q4:写操作被熔断会不会丢数据? 会。写类操作必须靠重试、补偿或最终一致机制处理,不能简单丢弃;读类操作才适合直接返回兜底值。

小结

  • 熔断是依赖故障时的快速失败开关,三态切换由错误率与慢调用比例驱动。
  • 熔断必须配降级,否则只是把超时变成立即报错。
  • 阈值从 SLO 反推,再用压测校准,避免误熔断。
笔记加载中…