我已经设置了gunicorn与3个工人,30个工人连接和使用eventlet工人类。它被设置在Nginx后面。每请求几次,我就会在日志里看到这个。

[ERROR] gunicorn.error: WORKER TIMEOUT (pid:23475)
None
[INFO] gunicorn.error: Booting worker with pid: 23514

为什么会这样?我怎样才能知道哪里出了问题呢?


当前回答

我们在使用Django+nginx+gunicorn时也遇到了同样的问题。从Gunicorn文档中,我们配置了优雅的超时,几乎没有什么不同。

经过一些测试,我们找到了解决方案,要配置的参数是:timeout(并且不是优雅超时)。它走得像时钟一样快。

所以,做:

1)打开gunicorn配置文件

2)将TIMEOUT设置为您需要的任何值-以秒为单位

NUM_WORKERS=3
TIMEOUT=120

exec gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--timeout $TIMEOUT \
--log-level=debug \
--bind=127.0.0.1:9000 \
--pid=$PIDFILE

其他回答

这个端点是否花费了太多时间?

也许你使用的flask没有异步支持,所以每个请求都会阻塞调用。要创建异步支持而不让make变得困难,可以添加gevent worker。

使用gevent,一个新的调用将产生一个新的线程,你的应用程序将能够接收更多的请求

pip install gevent
gunicon .... --worker-class gevent

我在Docker中也遇到了同样的问题。

在Docker中,我保持训练过的LightGBM模型+ Flask服务请求。作为HTTP服务器,我使用gunicorn 19.9.0。当我在我的Mac笔记本电脑上本地运行我的代码时,一切都很完美,但当我在Docker中运行应用程序时,我的POST JSON请求冻结了一段时间,然后gunicorn工人已经失败了[CRITICAL]工人超时异常。

我尝试了大量不同的方法,但唯一解决我的问题的是添加worker_class=gthread。

以下是我的完整配置:

import multiprocessing

workers = multiprocessing.cpu_count() * 2 + 1
accesslog = "-" # STDOUT
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(q)s" "%(D)s"'
bind = "0.0.0.0:5000"
keepalive = 120
timeout = 120
worker_class = "gthread"
threads = 3

除了已经建议的gunicorn超时设置,因为你在前面使用nginx,你可以检查这两个参数是否有效,proxy_connect_timeout和proxy_read_timeout默认为60秒。可以在nginx配置文件中这样设置它们,

proxy_connect_timeout 120s;
proxy_read_timeout 120s;

检查你的工人没有被健康检查杀死。长请求可能会阻塞健康检查请求,worker会被平台杀死,因为平台认为worker没有响应。

例如,如果您有一个25秒长的请求,并且活动检查被配置为每10秒命中同一服务中的不同端点,1秒超时,并重试3次,这就给出了10+1*3 ~ 13秒,您可以看到它会触发一些时间,但并不总是如此。

如果是这种情况,解决方案是重新配置您的活动检查(或您的平台使用的任何健康检查机制),以便它可以等待您的典型请求完成。或者允许更多的线程——这样可以确保健康检查不会阻塞足够长的时间来触发worker kill。

你可以看到,增加更多的工人可能有助于(或隐藏)这个问题。

关于在Azure应用服务(Linux应用)上运行Flask Apps的Microsoft Azure官方文档声明超时时间为600

gunicorn --bind=0.0.0.0 --timeout 600 application:app

https://learn.microsoft.com/en-us/azure/app-service/configure-language-python#flask-app