nginx reload 时旧 worker 怎么退出?长连接会让旧 worker 堆积吗?worker_shutdown_timeout 起什么作用?reload、quit、stop 对在途请求和新连接分别意味着什么?这篇用 nginx 1.31.6 逐项量出来。
配置 | 在途的 3 s 请求 | reload 之后的进程 | reload 之后的新请求 | 旧 worker 在 reload 之后多久退出 ---------------------------+----------------+--------------------------------------------------+---------------+------------------------- 默认 | 200 · 3.01 s | reload 后 0.3 s:2 个 worker(其中 1 个在 shutting down) | 200 · 1 ms | 2.5 s worker_shutdown_timeout 1s | error · 1.63 s | reload 后 0.3 s:2 个 worker(其中 1 个在 shutting down) | 200 · 1 ms | 1.2 s reload 不会打断在途的请求:旧 worker 把手上的请求处理完才退出,新 worker 马上开始接新连接;设了 worker_shutdown_timeout 之后,到点旧 worker 强行关闭还没结束的连接,在途请求会失败
旧 worker 把手上的请求处理完再退出;worker_shutdown_timeout 到点强行结束。
配置 | 每轮 reload 后 1 s 的 worker 数(括号里是 shutting down 的) | 3 轮之后再过 2.5 s | client 的长连接还活着的 | 关掉所有 client 之后 1 s ---------------------------+--------------------------------------------------+---------------+-----------------+------------------- 默认 | 2(1) → 3(2) → 4(3) | 4(3) | 6 / 6 | 1(0) worker_shutdown_timeout 2s | 2(1) → 2(1) → 2(1) | 1(0) | 0 / 6 | 1(0) 每次 reload 产生一个新 worker,旧 worker 只要还有一条长连接就不会退出:不设 worker_shutdown_timeout 时旧 worker 一直堆积(每次发布多一个),直到 client 自己断开;设了超时,到点长连接被强行断开(client 读到 EOF),旧 worker 才退出
只要还有长连接,旧 worker 就不退出;每次发布多一个。
操作 | 在途的 2 s 请求 | 操作之后 3 s 里新请求的结果(状态码:个数)
-----------+----------------+-------------------------
reload | 200 · 2.01 s | {200: 28}
quit(优雅退出) | 200 · 2.01 s | {'error': 28}
stop(快速退出) | error · 0.53 s | {'error': 29}
quit 让 master 立刻关闭监听端口、不再接新连接,等在途请求处理完再退出:在途请求成功,但新连接在 nginx 退出前后一直被拒绝(状态是 error 表示连接被拒或重置),在发布时应当先把流量摘走再 quit;stop 立刻结束,在途请求失败;reload 监听端口不关,新连接一直成功reload 不关监听端口;quit 关监听端口但等在途请求;stop 立刻结束。