Nginx原生不支持断路器,但OpenResty可通过Lua共享字典实现Closed/Open/Half-Open三态熔断,支持按接口路径粒度统计错误率、耗时并动态降级,需配合access_by_lua_block判断、log_by_lua_block更新状态及滑动窗口清理过期数据。

Nginx 本身不支持断路器(Circuit Breaker)模式,但借助 OpenResty(Nginx + Lua),可以在网关层实现贴近标准三态(Closed/Open/Half-Open)的逻辑熔断。这不是简单的健康检查屏蔽,而是基于请求结果、时间窗口和状态记忆的主动干预机制。
核心状态机需由 Lua 维护
原生 Nginx 的 max_fails 只做节点剔除,无法区分接口粒度、无法统计错误率、也无法回退到半开试探。OpenResty 则可通过共享字典(lua_shared_dict)持久化每个服务或路径的状态:
- Closed 状态:正常转发,同时用定时器或滑动窗口记录最近 N 次响应码、耗时、是否超时
-
Open 状态:直接返回预设降级响应(如
503 Service Unavailable+ JSON 提示),不发往后端 - Half-Open 状态:仅放行固定数量(如 3 个)请求试探;全部成功则切回 Closed,任一失败则重置倒计时并维持 Open
关键配置与数据协同
要让熔断真正生效,需在 Nginx 配置中预留必要基础:
- 声明共享内存区:
lua_shared_dict fuse_shard_dict 10m;(用于存状态、计数器、时间戳) - 在
access_by_lua_block中执行熔断判断逻辑,根据 URI、上游名或 header 动态选择熔断 key - 在
log_by_lua_block中更新状态:成功/失败/超时各触发不同计数器累加与时间刷新 - 配合 Redis 可跨 Nginx 实例同步状态,适合多节点网关集群场景
按接口路径做精确熔断
业务常需对特定高危接口(如第三方支付回调、OCR 识别)单独熔断,而不影响同服务其他路径。OpenResty 支持按 ngx.var.uri 或正则匹配提取特征,例如:
- 将
/api/v1/face/verify和/api/v1/face/detect视为独立熔断单元 - 失败阈值可差异化设置:前者设为 5 次失败/60 秒,后者放宽至 10 次/120 秒
- 熔断后自动切换兜底行为:返回缓存结果、调用备用供应商、或转异步队列延后处理
避免常见误用陷阱
实践中容易把“限流”当“熔断”,或把“被动踢节点”当“主动断路”。需注意:
-
不要只依赖
proxy_next_upstream:它只是重试,不阻止后续请求继续打向已故障节点 - fail_timeout 不等于熔断冷却期:前者是 Nginx 内部标记失效时长,后者需 Lua 控制并可动态调整
- 状态必须带时间上下文:单纯计数会累积历史噪音,应结合滑动窗口或 TTL 自动清理过期数据
-
半开试探需限流保护:防止试探请求本身引发新雪崩,建议配合
limit_req控制试探频次


















