Docker中Gunicorn遇“Worker (pid:649) was sent SIGTERM!”错误的排查与优化
SIGTERM错误原因分析
核心触发场景
- Gunicorn主进程主动重启Worker:当Worker进程因内存泄漏、长时间无响应等问题异常时,Gunicorn主进程会发送SIGTERM信号终止该Worker并重启新的Worker。当前配置未设置Worker生命周期限制,若Flask应用存在内存泄漏,会导致Worker占用内存持续升高,触发主进程的重启机制。
- Docker资源回收机制:Windows Docker Desktop分配给容器的CPU/内存资源不足时,系统OOM Killer会强制杀掉占用资源最高的进程;或Docker Desktop后台更新、重启时,会向容器发送SIGTERM信号终止所有进程。
- 跨平台信号传递异常:Windows环境下运行Linux容器,信号处理机制存在兼容性差异,可能导致偶发的SIGTERM信号误触发。
- 缺失健康检查:Docker无法感知容器内API的运行状态,若服务出现短暂不可用,Docker可能强制终止并重启容器,间接导致Worker收到SIGTERM。
配置优化方案
调整Gunicorn Worker生命周期(修改gunicorn.conf.py)
添加Worker重启策略和超时设置,避免内存泄漏和无响应问题:
import multiprocessing # 基于容器CPU核心数动态计算Worker数量,适配Docker资源 workers = 2 * multiprocessing.cpu_count() + 1 loglevel = "debug" accesslog = "-" errorlog = "-" # 单独输出错误日志,便于排查 capture_output = True enable_stdio_inheritance = True # 限制Worker处理请求数,定期重启防止内存泄漏 max_requests = 1000 max_requests_jitter = 100 # 随机波动时间,避免所有Worker同时重启 timeout = 30 # Worker超过30秒未响应则终止 graceful_timeout = 10 # 收到SIGTERM后,等待10秒处理完现有请求再退出
优化Docker配置
- 添加健康检查:让Docker实时监控服务状态,避免误杀容器(需Flask提供
/health接口)
# ... 原有Dockerfile内容 ... HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \ CMD curl -f http://localhost:5000/health || exit 1 CMD ["gunicorn", "-b", "0.0.0.0:5000", "-c", "gunicorn.conf.py", "run:app"]
- 使用轻量镜像:替换为
python:3.10-slim减少镜像体积和资源占用
FROM python:3.10-slim
限制容器资源
启动容器时明确设置CPU和内存配额,避免触发OOM Killer:
docker run -d -p 5000:5000 --memory=512m --cpus=1 your-image-tag
Flask应用优雅关闭
添加SIGTERM信号处理,确保服务关闭时完成现有请求:
from flask import Flask import signal import sys app = Flask(__name__) def handle_sigterm(signal_num, frame): print("SIGTERM received, shutting down gracefully") sys.exit(0) signal.signal(signal.SIGTERM, handle_sigterm) # ... 你的路由和业务逻辑 ...
内容的提问来源于stack exchange,提问作者Elie
相关产品推荐
相关产品推荐

