fail_timeout通过设定故障节点静默期来阻断https雪崩:在fail_timeout窗口内跳过失败节点,避免重复tls握手耗尽资源;需与max_fails联动,并配合proxy_connect_timeout、proxy_ssl_verify等加密专用参数协同生效。

fail_timeout 本身不是加密连接专用参数,它属于 Nginx upstream 模块的健康检查机制,作用是:当某台后端服务器被标记为“失败”后,在 fail_timeout 设定的时间窗口内,Nginx 不会将新请求转发给它。这个时间窗口策略,恰恰是缓解 TLS/HTTPS 加密连接雪崩的关键缓冲带。
fail_timeout 如何切断加密连接雪崩链
HTTPS 雪崩常始于加密握手失败(如证书过期、TLS 版本不兼容、OCSP 响应慢)或后端 SSL 终止服务异常(如 nginx + openssl 升级后 handshake hang)。一旦某台上游节点因 TLS 错误连续失败,若无隔离机制,Nginx 仍会持续尝试转发——每次失败都经历完整 TCP 握手 + TLS 握手 + 等待超时,耗尽连接槽位与 worker 资源,拖垮整个 upstream 组。
fail_timeout 配合 max_fails 使用,构成“失败计数+冷静期”闭环:
- max_fails=3:连续 3 次请求在 proxy_connect_timeout 或 proxy_ssl_verify 阶段失败(如 SSL handshake timeout、SSL certificate error),即触发标记
- fail_timeout=30s:该节点进入 30 秒“静默期”,期间所有新请求直接跳过它,由其他健康节点承接
- 30 秒后自动恢复探测;若仍失败,重新计时
必须同步配置的加密相关配套项
仅设 fail_timeout 不足以覆盖 HTTPS 全链路风险,需精准控制各阶段超时边界:
- proxy_connect_timeout 5s:限制建立到 upstream 的 TCP 连接时间,防止 TLS 握手卡在 SYN 或 Server Hello 阶段无限等待
- proxy_ssl_protocols TLSv1.2 TLSv1.3:显式禁用老旧协议(如 TLSv1.0),避免因协商失败反复重试
- proxy_ssl_verify on 且配好 proxy_ssl_trusted_certificate:主动校验证书链,失败立即报错并计入 max_fails,不等到读响应才崩溃
- proxy_ssl_session_reuse on:复用 TLS session ticket,减少重复 handshake 开销,降低单位连接失败概率
真实场景中的典型配置组合
以面向公网的 API 网关为例(后端为多台 TLS 终止的 Nginx 或 Envoy):
upstream api_backend {
server 10.0.1.10:443 max_fails=2 fail_timeout=15s;
server 10.0.1.11:443 max_fails=2 fail_timeout=15s;
server 10.0.1.12:443 max_fails=2 fail_timeout=15s;
keepalive 32;
}
server {
location /api/ {
proxy_pass https://api_backend;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
proxy_ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/nginx/ssl/ca-bundle.crt;
proxy_ssl_session_reuse on;
}
}
该配置使单点 TLS 故障的影响被严格限制在 15 秒内,且仅影响该节点承载的流量份额,不会引发全量重试风暴。
验证是否生效的实操方法
不依赖日志猜测,用可复现方式验证:
- 临时在某台 upstream 机器上 mv /etc/nginx/ssl/fullchain.pem /tmp/ 模拟证书丢失
- 用 curl -vI https://your-gateway/api/test 持续请求,观察前 2 次返回 502(SSL handshake failed),第 3 次起稳定由其他节点响应
- 执行 nginx -T | grep -A5 "upstream api_backend" 确认 fail_timeout 已加载
- 检查 nginx_stub_status 中 Active connections 波动平缓,无突增后骤降现象











