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

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

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


当前回答

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

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

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

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

其他回答

弗兰克的回答给我指明了正确的方向。我有一个数字海洋液滴访问管理数字海洋Postgresql数据库。我所需要做的就是将我的液滴添加到数据库的“可信来源”。

(在DO控制台点击数据库,然后点击设置。编辑Trusted Sources,选择液滴名称(在可编辑区域点击,会提示)。

你需要使用另一个worker类型类,比如gevent或tornado。 第一个解释:

如果您预计应用程序代码在请求处理期间可能需要暂停较长时间,您可能还需要安装Eventlet或Gevent

第二点:

默认的同步工作线程假定您的应用程序在CPU和网络带宽方面受到资源限制。通常这意味着您的应用程序不应该执行任何花费未定义时间的操作。例如,对互联网的请求就符合这个标准。在某些时候,外部网络会出现故障,客户端会堆积在您的服务器上。

以我为例,我在向服务器发送较大(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

超时是这个问题的一个关键参数。

然而,它不适合我。

当我设置workers=1时,我发现没有gunicorn超时错误。

当我看我的代码,我发现一些套接字连接(套接字。在服务器init中发送& socket.recv)。

套接字。Recv将阻塞我的代码,这就是为什么它总是超时时,工人>1

希望能给那些对我有意见的人一些建议

使用——log-level debug运行Gunicorn。

它应该会给你一个应用程序堆栈跟踪。