跳到主要内容

a6-recipe-circuit-breaker

概览

熔断器通过检测不健康的上游并暂时停止向其发送请求,避免故障在服务之间级联。当上游返回过多错误时,熔断器进入“开启”状态,APISIX 会立即返回错误而不再转发请求。冷却期结束后,熔断器进入“半开”状态,用少量请求测试上游是否已经恢复。

APISIX 通过 api-breaker 插件实现熔断。该插件会跟踪响应状态码,并自动管理熔断状态。

适用场景

  • 当上游发生故障时,保护您的API免受级联故障的影响
  • 自动停止向出现故障的后端发送流量
  • 为故障服务预留恢复时间,再尝试发送请求
  • 返回快速错误响应,而不是等待超时

熔断器状态

          ┌─────────┐
│ CLOSED │ ← Normal operation: requests flow through
│(healthy) │
└────┬─────┘
│ Error count exceeds threshold

┌─────────┐
│ OPEN │ ← Breaker tripped: returns 502 immediately
│(tripped) │
└────┬─────┘
│ After cooldown period

┌──────────┐
│HALF-OPEN │ ← Test: allows one request through
│ (testing) │
└─────┬────┘

┌───────┴───────┐
│ │
Success Failure
│ │
▼ ▼
CLOSED OPEN (longer cooldown)

插件配置参考

字段是否必填说明
break_response_code熔断开启时返回的 HTTP 状态码
break_response_body熔断开启时返回的响应体
break_response_headers熔断开启时返回的响应头
unhealthy.http_statuses计为不健康的上游状态码
unhealthy.failures开启熔断前所需的连续不健康响应次数
healthy.http_statuses用于恢复的健康状态码
healthy.successes关闭熔断前所需的连续健康响应次数
max_breaker_sec熔断开启的最长时间

熔断时间

熔断器开启后,冷却时间按指数增长:

  1. 首次开启:冷却 2 秒
  2. 再次开启:冷却 4 秒
  3. 后续依次为 8 秒16 秒,以此类推
  4. 最长不超过 max_breaker_sec(默认 300 秒,即 5 分钟)

冷却期间,所有请求都会立即获得break_response_code

分步操作:启用熔断

1. 基本熔断器

a6 route create -f - <<'EOF'
{
"id": "protected-api",
"uri": "/api/*",
"plugins": {
"api-breaker": {
"break_response_code": 502,
"unhealthy": {
"http_statuses": [500, 502, 503],
"failures": 3
},
"healthy": {
"http_statuses": [200],
"successes": 3
},
"max_breaker_sec": 300
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 1
}
}
}
EOF

连续收到 3 次 500、502 或 503 响应后,熔断器开启并立即返回 502。冷却期结束后,APISIX 会发送请求进行探测;连续收到 3 次 200 响应后,熔断器关闭并恢复正常转发。

2. 使用自定义错误响应体

a6 route create -f - <<'EOF'
{
"id": "api-with-error-body",
"uri": "/api/*",
"plugins": {
"api-breaker": {
"break_response_code": 503,
"break_response_body": "{\"error\": \"service temporarily unavailable\", \"retry_after\": 30}",
"break_response_headers": [
{"key": "Content-Type", "value": "application/json"},
{"key": "Retry-After", "value": "30"}
],
"unhealthy": {
"http_statuses": [500, 502, 503, 504],
"failures": 5
},
"healthy": {
"http_statuses": [200, 201, 204],
"successes": 2
},
"max_breaker_sec": 60
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 1
}
}
}
EOF

3. 敏感熔断器(首次错误即触发)

{
"plugins": {
"api-breaker": {
"break_response_code": 503,
"unhealthy": {
"http_statuses": [500, 502, 503],
"failures": 1
},
"healthy": {
"http_statuses": [200],
"successes": 1
},
"max_breaker_sec": 30
}
}
}

首个 5xx 错误即触发熔断,随后一次成功响应即可恢复。

与健康检查相结合

生产环境建议将熔断器与上游健康检查结合使用。熔断器在路由级别提供保护,健康检查则管理上游中每个节点的健康状态。

# Create upstream with health checks
a6 upstream create -f - <<'EOF'
{
"id": "monitored-backend",
"type": "roundrobin",
"nodes": {
"backend-1:8080": 1,
"backend-2:8080": 1
},
"checks": {
"active": {
"type": "http",
"http_path": "/health",
"healthy": {
"interval": 5,
"successes": 2
},
"unhealthy": {
"interval": 3,
"http_failures": 3
}
}
}
}
EOF

# Create route with circuit breaker
a6 route create -f - <<'EOF'
{
"id": "api",
"uri": "/api/*",
"plugins": {
"api-breaker": {
"break_response_code": 503,
"unhealthy": {
"http_statuses": [500, 502, 503],
"failures": 3
},
"healthy": {
"http_statuses": [200],
"successes": 3
}
}
},
"upstream_id": "monitored-backend"
}
EOF

配置同步示例

version: "1"
routes:
- id: protected-api
uri: /api/*
plugins:
api-breaker:
break_response_code: 503
break_response_body: '{"error": "service unavailable"}'
break_response_headers:
- key: Content-Type
value: application/json
- key: Retry-After
value: "30"
unhealthy:
http_statuses: [500, 502, 503]
failures: 3
healthy:
http_statuses: [200]
successes: 3
max_breaker_sec: 300
upstream_id: backend
upstreams:
- id: backend
type: roundrobin
nodes:
"backend:8080": 1

故障排查

症状原因解决方法
熔断器从未开启unhealthy.http_statuses 未包含实际错误码添加上游实际返回的错误状态码
熔断保持时间过长max_breaker_sec 过高降低 max_breaker_sec 以加快恢复
熔断器频繁开启和关闭阈值过低,且上游存在间歇性错误提高 unhealthy.failures 阈值
502 由 APISIX 返回,而非自定义熔断响应上游无法连接(例如连接被拒绝)连接错误同样会计入不健康阈值
恢复过慢healthy.successes 过高降低 healthy.successes 以加快恢复

本文根据 api7/a6 仓库中的 a6-recipe-circuit-breaker/SKILL.md 生成。可在 AI Agent Skills 页面浏览全部 Skill。