我已经设置了gunicorn与3个工人,30个工人连接和使用eventlet工人类。它被设置在Nginx后面。每请求几次,我就会在日志里看到这个。
[ERROR] gunicorn.error: WORKER TIMEOUT (pid:23475)
None
[INFO] gunicorn.error: Booting worker with pid: 23514
为什么会这样?我怎样才能知道哪里出了问题呢?
我已经设置了gunicorn与3个工人,30个工人连接和使用eventlet工人类。它被设置在Nginx后面。每请求几次,我就会在日志里看到这个。
[ERROR] gunicorn.error: WORKER TIMEOUT (pid:23475)
None
[INFO] gunicorn.error: Booting worker with pid: 23514
为什么会这样?我怎样才能知道哪里出了问题呢?
当前回答
超时是这个问题的一个关键参数。
然而,它不适合我。
当我设置workers=1时,我发现没有gunicorn超时错误。
当我看我的代码,我发现一些套接字连接(套接字。在服务器init中发送& socket.recv)。
套接字。Recv将阻塞我的代码,这就是为什么它总是超时时,工人>1
希望能给那些对我有意见的人一些建议
其他回答
WORKER TIMEOUT表示应用程序不能在规定的时间内响应请求。你可以使用gunicorn超时设置来设置。一些应用程序需要比另一个应用程序更多的时间来响应。
另一个可能影响这一点的因素是员工类型的选择
The default synchronous workers assume that your application is resource-bound in terms of CPU and network bandwidth. Generally this means that your application shouldn’t do anything that takes an undefined amount of time. An example of something that takes an undefined amount of time is a request to the internet. At some point the external network will fail in such a way that clients will pile up on your servers. So, in this sense, any web application which makes outgoing requests to APIs will benefit from an asynchronous worker.
当我遇到与您相同的问题时(我试图使用Docker Swarm部署我的应用程序),我尝试增加超时并使用另一种类型的工人类。但都失败了。
然后我突然意识到我的资源限制太低在我的撰写文件中的服务。在我的例子中,这就是减慢应用程序的原因
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
所以我建议你先检查一下是什么减慢了你的应用程序
检查你的工人没有被健康检查杀死。长请求可能会阻塞健康检查请求,worker会被平台杀死,因为平台认为worker没有响应。
例如,如果您有一个25秒长的请求,并且活动检查被配置为每10秒命中同一服务中的不同端点,1秒超时,并重试3次,这就给出了10+1*3 ~ 13秒,您可以看到它会触发一些时间,但并不总是如此。
如果是这种情况,解决方案是重新配置您的活动检查(或您的平台使用的任何健康检查机制),以便它可以等待您的典型请求完成。或者允许更多的线程——这样可以确保健康检查不会阻塞足够长的时间来触发worker kill。
你可以看到,增加更多的工人可能有助于(或隐藏)这个问题。
我有非常相似的问题,我也尝试使用“运行服务器”,看看我是否能找到任何东西,但我所拥有的只是一个消息杀死
所以我认为这可能是资源问题,我继续给实例更多的RAM,它工作了。
这个端点是否花费了太多时间?
也许你使用的flask没有异步支持,所以每个请求都会阻塞调用。要创建异步支持而不让make变得困难,可以添加gevent worker。
使用gevent,一个新的调用将产生一个新的线程,你的应用程序将能够接收更多的请求
pip install gevent
gunicon .... --worker-class gevent
以我为例,我在向服务器发送较大(10MB)文件时遇到了这个问题。我的开发服务器(app.run())收到他们没有问题,但gunicorn无法处理他们。
和我遇到同样问题的人。我的解决方案是像这样把它分成块发送: 参考/ HTML的例子,单独的大文件参考
def upload_to_server():
upload_file_path = location
def read_in_chunks(file_object, chunk_size=524288):
"""Lazy function (generator) to read a file piece by piece.
Default chunk size: 1k."""
while True:
data = file_object.read(chunk_size)
if not data:
break
yield data
with open(upload_file_path, 'rb') as f:
for piece in read_in_chunks(f):
r = requests.post(
url + '/api/set-doc/stream' + '/' + server_file_name,
files={name: piece},
headers={'key': key, 'allow_all': 'true'})
我的烧瓶服务器:
@app.route('/api/set-doc/stream/<name>', methods=['GET', 'POST'])
def api_set_file_streamed(name):
folder = escape(name) # secure_filename(escape(name))
if 'key' in request.headers:
if request.headers['key'] != key:
return 404
else:
return 404
for fn in request.files:
file = request.files[fn]
if fn == '':
print('no file name')
flash('No selected file')
return 'fail'
if file and allowed_file(file.filename):
file_dir_path = os.path.join(app.config['UPLOAD_FOLDER'], folder)
if not os.path.exists(file_dir_path):
os.makedirs(file_dir_path)
file_path = os.path.join(file_dir_path, secure_filename(file.filename))
with open(file_path, 'ab') as f:
f.write(file.read())
return 'sucess'
return 404