部署新版本时,正在处理的请求会怎么样?不同信号对 gunicorn 的效果差别很大。这篇用真实的 gunicorn,让一个 3 秒的请求处于进行中,逐个发信号,看请求结果、退出时间、atexit 和 worker_exit 钩子(容器里的信号传递见第 189 篇)。
那个进行中的请求 → 200 done by 7258,耗时 3.01 s | 关闭开始 0.5 秒后的新连接 → ConnectionResetError | master 退出用了 2.66 s
日志:
[2026-10-02 15:49:53 +0800] [72585] [INFO] Booting worker with pid: 72585
[2026-10-02 15:49:54 +0800] [72583] [INFO] Handling signal: term
[2026-10-02 15:49:56 +0800] [72585] [INFO] Worker exiting (pid: 72585)
[2026-10-02 15:49:56 +0800] [72583] [INFO] Shutting down: Master
worker 里 atexit 是否运行: ['atexit in pid 72585'] | worker_exit 钩子: ['worker_exit hook pid 72585']实验用 1 个 sync worker 与 2 个 worker 两种配置,请求是 time.sleep(3)。
信号 进行中的请求 master 退出(s) atexit worker_exit 钩子 SIGTERM 200 done by 7263 (3.02 s) 2.68 1 1 SIGINT 500 (错误页 141 字节) (0.71 s) 0.35 1 1 SIGQUIT 500 (错误页 141 字节) (0.71 s) 0.35 1 1 SIGKILL 200 done by 7268 (3.02 s) 0.01 1 1
进行中的请求 → RemoteDisconnected,1.67 s 后;master 退出 1.08 s
日志:
[2026-10-02 15:50:13 +0800] [72714] [INFO] Booting worker with pid: 72714
[2026-10-02 15:50:13 +0800] [72712] [INFO] Handling signal: term
[2026-10-02 15:50:14 +0800] [72712] [INFO] Shutting down: Master
worker 里 atexit: 0 次 | worker_exit 钩子: 0 次(日志里没有 Worker exiting)HUP 之前的 worker pid:2 个;HUP 之后:2 个,与之前重叠 0 个(全部更换) 进行中的 3 秒请求 → 200 done by 7273,3.0 s;期间 62 次 /pid 请求,失败 0 次;请求中见过的不同 worker pid 数 3 worker_exit 钩子: 2 次,atexit: 2 次