Nginx中安全下线微服务需业务层预下线(停新请求、处理存量)与upstream_check探测协同:后者仅标记节点状态,不感知业务语义;配置须支持503或响应体匹配以识别主动下线。

在 Nginx 中实现后端微服务节点的“安全下线”,核心不是靠 upstream_check 模块直接控制,而是将其作为健康探测信号源,配合自定义逻辑(如主动摘除、优雅等待、状态上报)共同完成。Upstream-Check 本身只负责周期性探测并标记节点为 down,真正的“安全”下线需由业务侧配合完成——即:先停止接收新请求,再等存量请求处理完,最后通知 Nginx 摘除。
理解 upstream_check 的角色与局限
Upstream-Check(通常指 nginx_upstream_check_module)是一个第三方模块,用于扩展 Nginx 的健康检查能力,支持 TCP、HTTP、SSL 等探测方式,并能动态标记后端为 down 或 up。但它不感知业务语义,无法判断“该节点是否还在处理请求”或“是否已进入预下线状态”。它只看探测响应是否符合预期(如 HTTP 200、超时、连接失败)。
因此,安全下线必须分两步走:
- 业务层主动进入“预下线模式”:关闭新请求入口(如停用 HTTP 端口、返回 503、拒绝注册到服务发现);同时保持旧连接继续处理,直到自然结束;
- Nginx 层通过 upstream_check 探测该“预下线状态”,一旦确认不可用,自动剔除节点,不再转发流量。
配置 upstream_check 实现可感知的健康探测
假设你有一个微服务集群,每个节点提供 /health/ready 接口,正常返回 {"status":"UP"},下线前会切换为 {"status":"DOWN", "reason":"draining"} 并返回 HTTP 503。
在 Nginx 配置中启用检查:
upstream backend_service {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
<pre class="brush:php;toolbar:false;"># 启用健康检查(需编译含 check 模块)
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_3xx; # 注意:若下线时返回 503,需加入 http_5xx}
关键点:
-
check_http_expect_alive必须包含http_5xx,否则 503 会被判为异常,触发fall计数,但你希望“返回 503 = 主动下线”,应视为有效探测结果并立即摘除; - 更稳妥做法是让下线接口返回 200 + JSON 标识,然后用
check_http_match匹配响应体(需支持该指令的 check 模块版本),例如: check_http_match "up": "status.*UP";
check_http_match "down": "status.*DOWN";
业务端配合:实现可探测的预下线流程
服务实例收到下线信号(如 Kubernetes 的 SIGTERM、Consul 的 deregister、运维脚本触发)后,应:
- 立即停止接受新连接(如关闭 Netty 的 acceptor、Spring Boot 的 Tomcat connector.pause());
- 维持已有长连接和正在处理的请求,设置合理超时(如 30–60 秒);
- 将
/health/ready接口响应切换为503 Service Unavailable或200 + {"status":"DRAINING"}; - (可选)调用 Nginx API 或 reload 配置,加速摘除(见下一条)。
进阶:结合 Nginx Plus 或 OpenResty 实现秒级摘除
社区版 Nginx 的 upstream_check 是被动探测,存在几秒延迟。若需更快响应,可考虑:
-
Nginx Plus:原生支持
health_check+match+API 动态更新 upstream,可通过curl -X PATCH立即设置某 server 为down; -
OpenResty + lua-resty-upstream-healthcheck:在 Lua 层监听业务上报的下线事件(如 Redis Pub/Sub、HTTP webhook),实时调用
balancer.set_current_peer()或修改共享字典中的节点状态,绕过探测延迟; -
外部协调器:用 Consul Template / confd 监听服务状态变更,自动生成 Nginx 配置并 reload(注意 reload 有毫秒级请求中断,需搭配
worker_shutdown_timeout和连接复用优化)。
不复杂但容易忽略的是:安全下线的本质是“时间窗口对齐”——业务要留够处理时间,Nginx 要及时停止派发,监控要能区分“故障宕机”和“计划下线”。Upstream-Check 是其中可靠的一环,但不是全部。











