按 Enter 键跳转到正文

高并发系统设计-熔断

高并发系统设计-熔断

一、概述

1.1 什么是熔断

熔断(Circuit Breaker)的核心思想来自电路保险丝:

当电流过大时,保险丝会断开,保护整个电路。

在分布式系统中:

服务A → 服务B → 服务C → 数据库

如果服务C异常:

  • 超时
  • 报错
  • 响应缓慢

那么如果不做控制:

A 等 BB 等 CC 卡住→ 线程全部阻塞→ 请求堆积→ 系统雪崩

熔断的作用就是:

当下游服务异常时,直接停止调用它,快速失败。

1.2 为什么需要熔断

在高并发系统中,最危险的问题不是“服务失败”,而是:

失败被放大并传播

例如:

数据库慢查询
   ↓
所有请求阻塞
   ↓
连接池耗尽
   ↓
Redis压力上升
   ↓
Gateway超时
   ↓
全链路崩溃

这就是:

级联故障(Cascade Failure)

1.3 熔断解决的问题

熔断解决三类问题:

1. 防止线程阻塞

避免请求一直等待下游:

请求 → 卡住 → 不释放资源

2.防止错误放大

错误不会扩散到上游系统:

错误服务 → 不再调用

1.4 企业典型场景

场景1:支付服务异常

订单服务 → 支付服务(异常)

不熔断:
→ 一直等待
→ 订单线程堆积

熔断后:
→ 直接返回“支付处理中”

场景2:库存服务不可用

库存服务挂了

熔断:
→ 不再调用库存
→ 返回“库存未知”

场景3:第三方接口超时

例如:

  • 短信平台
  • 邮件服务
  • 地图API

熔断避免拖垮主系统。

二、原理

2.1 熔断的核心思想

熔断本质是一个:

状态机 + 失败统计 + 自动恢复机制

2.2 三种状态模型

熔断器包含三个状态:

        +---------+
        | CLOSED   |
        +---------+
             |
        失败率过高
             ▼
        +---------+
        | OPEN     |
        +---------+
             |
        冷却时间
             ▼
        +--------------+
        | HALF-OPEN    |
        +--------------+

2.3 状态解释

1.CLOSED(关闭状态)

正常状态:请求正常通过

此时:

  • 记录成功/失败次数
  • 监控错误率

2.OPEN(熔断状态)

触发条件:失败率 > 阈值

行为:

  • 直接拒绝请求
  • 不再访问下游
  • 快速返回 fallback

3.HALF-OPEN(半开状态)

作用:

用少量请求探测服务是否恢复

如果成功:恢复 CLOSED

如果失败:回到 OPEN

2.4 熔断触发条件

常用触发策略:

1. 失败率

如:失败率 > 50%

2.连续失败次数

如:连续失败 10 次

3. 慢调用

如:响应 > 2s 的请求比例过高

4.超时比例

如:超时率 > 30%

2.5 熔断恢复机制

恢复过程:

OPEN
  ↓(冷却时间)
HALF-OPEN
  ↓
成功 → CLOSED
失败 → OPEN

三、实现

PHP 简易熔断器实现

 1class CircuitBreaker
 2{
 3    private int $failCount = 0;
 4    private int $successCount = 0;
 5
 6    private int $threshold = 5;
 7    private string $state = 'CLOSED';
 8    private int $openTime = 0;
 9    private int $coolDown = 10;
10
11    public function call(callable $callback)
12    {
13        if ($this->state === 'OPEN') {
14            if (time() - $this->openTime < $this->coolDown) {
15                throw new Exception("Circuit Open");
16            }
17
18            $this->state = 'HALF_OPEN';
19        }
20
21        try {
22            $result = $callback();
23
24            $this->onSuccess();
25
26            return $result;
27        } catch (\Throwable $e) {
28            $this->onFailure();
29
30            throw $e;
31        }
32    }
33
34    private function onSuccess()
35    {
36        $this->failCount = 0;
37
38        if ($this->state === 'HALF_OPEN') {
39            $this->state = 'CLOSED';
40        }
41    }
42
43    private function onFailure()
44    {
45        $this->failCount++;
46
47        if ($this->failCount >= $this->threshold) {
48            $this->state = 'OPEN';
49            $this->openTime = time();
50        }
51    }
52}

Redis 分布式熔断状态存储结构示例

circuit:user-service

{
  state: OPEN,
  fail: 10,
  success: 0,
  open_time: 123456
}

发表评论