Gunicorn master进程会主动杀掉worker,常见触发点包括:--timeout超时强杀、--max-requests处理完指定请求数后优雅退出、keep-alive空闲超时判定卡死、preload未启用导致模块导入异常,以及系统OOM killer干预。

不是代码崩溃才重启,Gunicorn 自身的健康检查和资源策略会主动杀掉 worker。
worker 被 master 主动 kill 的常见触发点
Gunicorn 的 master 进程不只等 worker 崩溃才动作,它会按配置定期检查并强制终止“不健康”的 worker:
-
--timeout(默认 30 秒):worker 处理单个请求超时,master 直接kill -9并拉新进程 -
--keep-alive(默认 5 秒):HTTP keep-alive 连接空闲超时后,worker 若未及时退出,可能被判定为卡死 -
--max-requests和--max-requests-jitter:worker 处理完指定请求数后主动退出(防内存泄漏),不是错误但会表现为“意外重启” -
--preload未启用时,每个 worker 独立导入应用模块——若模块里有全局状态或未加锁的共享资源,可能引发不可预测行为,导致 worker 异常退出
日志里看不到 traceback?那大概率是超时或软退出
如果 gunicorn.error.log 里只有类似 Worker exiting after N requests 或 Worker timeout (pid:1234),而没有 Python 异常堆栈,说明不是你的业务代码抛了未捕获异常,而是 Gunicorn 主动干预:
- 用
--log-level debug启动,能捕获到Shutting down worker、Booting worker的精确时间戳,对比请求日志可定位是否集中发生在某类长耗时接口 -
--timeout对同步 worker(sync)影响最直接;对uvicorn.workers.UvicornWorker,还要注意 Uvicorn 自身的--timeout-keep-alive是否与 Gunicorn 冲突 - 别忽略系统级 OOM killer:
dmesg -T | grep -i "killed process"可查是否因内存爆掉被系统干掉,此时 worker 退出码是 137,不是 Python 异常
为什么加了 try-except 还拦不住重启?
因为很多重启根本不是 Python 层面的异常触发的:
立即学习“Python免费学习笔记(深入)”;
-
try-except拦不住--timeout杀进程:超时是 master 用信号(SIGKILL)强杀,Python 来不及执行任何 finally 或 handler -
--max-requests是 worker 主动调用os._exit(0),属于“优雅退出”,不会进 except - 子进程里开的线程没 join、或 C 扩展里有死锁,会导致 worker 卡住——这种卡住无法被 Python
except捕获,但会被 Gunicorn 的心跳检测判定为失联
真正要盯住的不是“为什么崩”,而是“谁在决定它该退”。Gunicorn 的重启逻辑藏在 master 的调度策略里,不是 bug,是设计;调参前先确认你看到的“意外”,到底是失控,还是它正在按你的配置严格执行。


















