我已经设置了一个在 Docker 容器内与 Gunicorn 一起运行的 Flask API(在 Windows 11 上使用 Docker Desktop)。一切似乎都工作正常,但我遇到了一个反复出现的问题。有时,我会在 Gunicorn 日志中看到以下错误消息:
[1] [ERROR] Worker (pid:649) was sent SIGTERM!
我提供了我的 Dockerfile 和 Gunicorn.conf.py 文件以供参考:
Dockerfile:
FROM python:3.10
# Creating Application Source Code Directory
RUN mkdir -p /usr/src/app
# Setting Home Directory
WORKDIR /usr/src/app
# Installing python dependencies
COPY requirements.txt /usr/src/app/
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
RUN python -m playwright install
RUN python -m playwright install-deps
# Copying src code to Container
COPY . /usr/src/app
# Exposing Ports
EXPOSE 5000
CMD ["gunicorn", "-b", "0.0.0.0:5000", "-c", "gunicorn.conf.py", "run:app"]
gunicorn.conf.py:
workers = 3 # 2 * (CPU cores) + 1
loglevel = "info"
accesslog = "-"
capture_output = True
enable_stdio_inheritance = True
如果有人深入了解为什么“Worker (pid:649) was sent SIGTERM!”发生错误或有改进配置的建议,我将非常感谢您的帮助。
如果worker启动时间过长,或者遇到超时,您还可以调整Gunicorn配置文件
gunicorn.conf.py
来增加worker数量或调整超时设置:
import multiprocessing
workers = multiprocessing.cpu_count() * 2 + 1 # Adjust the number of workers
timeout = 30 # Adjust the timeout as necessary, default is 30 seconds
graceful_timeout = 30 # Wait 30 seconds after a restart signal for workers to finish
loglevel = "info"
accesslog = "-"
errorlog = "-"
capture_output = True
enable_stdio_inheritance = True
正如评论所述,假设您的自定义 Gunicorn 工作线程能够处理 SIGTERM,如 Lucas Klassmann 的“在 Gunicorn 中处理 SIGTERM”中所示。
为了进行测试,您还可以尝试使用脚本启动 Gunicorn 以正确处理 SIGTERM,看看是否仍然存在相同的问题。
创建一个
gunicorn_starter.sh
文件(并使其可执行:chmod +x gunicorn_starter.sh
)
#!/bin/bash
function shutdown() {
echo "Shutting down Gunicorn gracefully..."
kill -SIGTERM "$pid"
wait "$pid"
}
# Trap SIGTERM from Docker stop command and forward to the Gunicorn process
trap shutdown SIGTERM
# Start Gunicorn with configurations
gunicorn -b 0.0.0.0:5000 -c gunicorn.conf.py run:app &
pid=$!
wait "$pid"
您需要将该文件添加到 Dockerfile 中的映像中:
# (the previous part of the Dockerfile remains unchanged)
# Exposing Ports
EXPOSE 5000
CMD ["/usr/src/app/gunicorn_starter.sh"]