零丢请求下线需nginx快速感知后端退出并停止新流量,同时保障已有请求完成:通过weight=0/down主动摘流、健康检查自动识别503状态、proxy_read_timeout等参数保障draining、后端协同停入口并等待连接归零。

要让后端服务下线时不丢请求、不断连接,核心不是“关掉 Nginx”,而是让 Nginx 快速感知后端退出意图,并停止派发新流量,同时给已有请求留出完成时间。这需要 Nginx 配置、后端行为和两者协作机制三者对齐。
主动摘流:用 weight=0 或 down 标记节点
这是最直接可控的下线方式。Nginx 不依赖后端发信号,而是靠配置显式控制流量走向:
- 在 upstream 块中将待下线节点设为 weight=0,Nginx 立即停止向其分发新请求,已有连接不受影响
- 或使用 down 参数(如
server 192.168.1.10:8080 down;),尤其适合 ip_hash 场景——哈希计算自动跳过 down 节点,老连接仍可正常收发 - 修改后执行
nginx -s reload,不中断服务;若用 OpenResty 或 nginx-upsync-module,还可免 reload 动态更新
健康检查配合:让 Nginx 自动识别退出状态
仅靠手动改配置不够灵活,需引入主动探测机制,让后端“自己说要下线”:
- 启用第三方模块
nginx_upstream_check_module(需编译时加入),在 upstream 中配置 HTTP 探活:check interval=3 rise=2 fall=3 timeout=1 type=http; - 后端下线前,将
/health或/actuator/health接口返回 503 Service Unavailable,触发 fall 计数,Nginx 在 3 次失败后自动标记该节点为不可用 - 注意:官方
health_check指令仅限 Nginx Plus;开源版必须用第三方模块或自行实现简易探测
保障 draining:延长连接处理窗口
摘流只是第一步,真正零丢失取决于 Nginx 是否给后端留足“善后时间”:
- 设置 proxy_read_timeout 为业务最长处理时间(如 60–120 秒),确保 Nginx 不会因超时中断后端正在处理的请求
- 开启 proxy_ignore_client_abort on,防止用户关闭页面导致 Nginx 提前终止后端还在跑的长任务
- 启用 proxy_http_version 1.1 和 proxy_set_header Connection "keep-alive",支持连接复用,减少重建开销
- upstream 内避免混用
keepalive和check,二者冲突会导致启动失败
后端协同:控制入口与退出节奏
Nginx 是被动协调者,后端必须主动配合才能闭环:
- 下线前先停用新请求入口:Spring Boot 可调
/actuator/refresh或关闭 Tomcat connector;Netty 可 shutdown EventLoopGroup - 保持已有连接可读写,等待活跃连接自然归零(可通过
stub_status监控 Active connections) - 确认无活跃连接后,再终止进程;若用 systemd,建议配置
TimeoutStopSec=90,匹配 proxy_read_timeout











