核心是确认Nginx故障转移是否破坏已有连接或导致中间态,关键在draining是否彻底、超时是否对齐、中间设备是否静默回收,以及客户端重连是否可控且幂等。

排查 Nginx 故障转移期间长连接断开重连逻辑,核心不是看“Nginx 有没有重连”,而是确认它是否在切换过程中破坏了已有连接、是否让客户端或后端陷入不可恢复的中间态。Nginx 本身不维护连接状态机,也不主动重建客户端长连接——它只负责当前连接的透传与转发。所谓“故障转移期间断连”,绝大多数是 draining 不彻底、配置未对齐、或中间设备干扰导致的被动中断。
确认故障转移是否真正完成 draining
Nginx 进程退出时若未等现有连接自然关闭,就会触发 RST 强制终止:
- 必须使用
nginx -s quit(而非stop或kill -9),确保 worker 进程优雅退出、连接 drain 完成 - systemd service 中需显式设置
TimeoutStopSec=30,避免超时后强制 kill - 若用 Keepalived 做 VIP 切换,
notify_stop脚本里要先发quit,等所有活跃连接 close 后再释放 VIP - 检查 error.log 是否有
worker process is shutting down日志,配合 tcpdump 抓包验证是否有 RST 包在 reload 后立即发出
检查上下游空闲超时是否对齐
故障转移常暴露超时错配问题:新节点启动后,旧连接还在,但因 timeout 设置不一致被单侧关闭:
- Nginx 的
keepalive_timeout(客户端侧)应略大于后端服务的 idle timeout(如 Tomcat 的connectionTimeout) - 流式或 WebSocket 场景下,
proxy_read_timeout必须 ≥ 后端心跳间隔 ×2(例如后端每 45 秒 ping 一次,此处设为 90–120s) - 后端服务自身也要开启 keep-alive 支持,并禁用连接池自动回收空闲连接(如 Spring Boot 的
server.tomcat.connection-timeout需显式调大)
排除中间设备静默回收干扰
云厂商 SLB、WAF、防火墙等常在故障转移窗口期“顺手”清理连接,表现为无日志、无错误码的突兀断开:
- 用
tcpdump -i any 'tcp[tcpflags] & (tcp-rst) != 0'抓包,定位 RST 发出方是客户端、Nginx 还是中间设备 - 检查云平台控制台中负载均衡器或 WAF 的 idle timeout 设置(常见默认值为 60–300s),需同步调大至与 Nginx 一致
- 在 upstream 块启用健康探测:
health_check interval=5 fails=2 passes=2;,让 Nginx 主动感知后端异常,避免将请求打到已失联节点
验证客户端重连行为是否可控
服务端无法替代客户端管理业务上下文,故障转移后的重连必须由前端或 SDK 主动发起且带状态标识:
- WebSocket 场景:前端监听
onclose,延迟 1–3 秒 + 指数退避后重连,并携带session_id或last_seq,由后端校验续接合法性 - HTTP 流式/SSE 接口:客户端应支持
Last-Event-ID头,后端据此恢复事件流位置,避免消息丢失或重复 - 所有重试请求必须透传
X-Idempotency-Key,后端结合 DB 唯一索引或 Redis 缓存做幂等判重,防止故障转移期间重复提交


















