无损下线需Nginx主动摘流、健康检查联动、保障draining及后端协同退出:设weight=0或down、配置check模块识别503、调大proxy_read_timeout、开启proxy_ignore_client_abort、后端拒新连并等连接归零。

要实现无损下线,核心不是等 Nginx “发现”后端挂了,而是让它提前避开、留足时间、配合收尾。Nginx 本身不监听 shutdown 信号,但通过配置与后端协同,可做到零请求丢失。
主动摘流:让 Nginx 立即停止派发新请求
这是最可控的第一步,确保下线过程从源头截断流量:
- 将待下线节点的
weight=0,例如:upstream backend { server 192.168.1.10:8080 weight=0; server 192.168.1.11:8080; }执行
nginx -s reload后,Nginx 立即停止向该节点分发新请求,已建立连接不受影响 - 或直接标为
down(尤其适用于ip_hash场景):server 192.168.1.10:8080 down;
哈希计算自动跳过该节点,老连接仍可正常读写
FastAPI Flask Proxy下载FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
健康检查联动:让后端“自己说要下线”
避免人工操作遗漏,引入自动识别机制:
- 启用
nginx_upstream_check_module(需编译时加入),配置 HTTP 探活:upstream backend { server 192.168.1.10:8080; check interval=3 rise=2 fall=3 timeout=1 type=http; check_http_send "GET /health/ready HTTP/1.1\r\nHost: example.com\r\n\r\n"; check_http_expect_alive http_2xx http_5xx; # 包含 503 才能识别主动下线 } - 后端准备下线时,将
/health/ready接口返回503 Service Unavailable,Nginx 在连续失败后自动标记节点为不可用
保障 draining:给存量请求留出完成时间
摘流之后,关键是让已在途请求跑完,不被中断:
- 设置
proxy_read_timeout为业务最长处理时间(如60s或120s),防止 Nginx 因超时强行切断后端正在处理的请求 - 开启
proxy_ignore_client_abort on,用户关闭页面或中断连接时,Nginx 不会因此终止后端仍在运行的任务 - 使用
proxy_http_version 1.1和proxy_set_header Connection "keep-alive",支持连接复用;upstream 中加keepalive 32减轻后端重建压力
后端必须承担退出节奏
Nginx 是协调者,真正决定“是否安全”的是后端行为:
- 收到
SIGTERM后,立即关闭新请求入口:停用 Tomcat connector、暂停 Netty EventLoop、或拒绝新 TCP 连接 - 保持已有连接可读写,不主动 close,等待活跃连接自然归零
- 通过
/status(stub_status)监控Active connections,确认归零后再终止进程 - 若用 systemd,配置
TimeoutStopSec=45,避免因超时被强制 kill
不复杂但容易忽略的是:nginx -s reload 不会中断已有连接,但必须确保 proxy_read_timeout 大于后端 draining 时间,否则 Nginx 会先断开。

















