gunicorn 有时会冻结,直到使用 Flask 的简单 docker Web 应用程序中的工作线程超时

问题描述 投票:0回答:2

我用 Flask 和 Gunicorn 构建了一个简单的 docker Web 应用程序。一切正常,但偶尔在发出请求时,响应会挂起。在工作人员超时之前,我在日志记录中看不到任何内容。因此,看起来工作人员正忙于某事,超时,然后新工作人员收到请求并立即响应。

我只用了 1 名工人就完成了安装。我知道我可以添加另一个工人。但除了我手动戳之外,没有其他请求。没有其他事情发生。所以我很好奇这个工作人员或主gunicorn工作人员还会在容器中做什么(心跳,错误处理那么昂贵)?

我的 Dockerfile:

FROM python:3.6-slim

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt --no-cache-dir

EXPOSE 5000

CMD ["gunicorn", "-w", "1", "-t", "30", "--worker-tmp-dir", "/dev/shm", "-b", "0.0.0.0:5000", "app:app"]

我的小应用程序:

import logging
import model
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.errorhandler(Exception)
def handle_error(e):
    code = 500
    app.log_exception(e)
    return jsonify(message=str(e)), code

@app.route("/predict", methods=["POST", "GET"])
def predict():
    result = model.predict(None)
    return jsonify(result)

model = model.mcascorer()

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')
else:
    gunicorn_logger = logging.getLogger('gunicorn.error')
    app.logger.handlers = gunicorn_logger.handlers
    app.logger.setLevel(gunicorn_logger.level)

我的超级小“模型”我称之为预测:

class mcascorer:

    def predict_proba(self, features):
        return 'hello'

    def predict(self, features):
        return 'hello'

通常会立即响应,但在超时期间日志如下所示:

[2020-05-21 18:09:28 +0000] [9] [DEBUG] Closing connection.

[2020-05-21 18:09:58 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:9)

[2020-05-21 18:09:58 +0000] [9] [INFO] Worker exiting (pid: 9)

[2020-05-21 18:09:58 +0000] [11] [INFO] Booting worker with pid: 11

[2020-05-21 18:09:58 +0000] [11] [DEBUG] GET /predict

工作人员似乎被其他事情阻碍了 - 但我不知道那会是什么。同时传入的心跳查询不应花费那么长时间,但它会挂起很多秒 - 我实际上为工作人员设置的整个超时持续时间。唯一发生的另一件事是错误日志记录,但不确定为什么会阻塞或花费这么长时间。即使它正在写入磁盘,这也看起来很奇怪。

我能找到的最接近的问题在这里:Docker:通过 Gunicorn 运行 Flask 应用程序 - Worker 超时?表现不佳? 链接到这篇文章: https://pythonspeed.com/articles/gunicorn-in-docker/

我按照他们的指南更新了 tmp 内存位置“--worker-tmp-dir”、“/dev/shm”的 Dockerfile

我没有添加更多工人。我知道我可以,但我真的很想知道发生了什么,而不是盲目地投入资源。任何想法都非常感激。

docker flask gunicorn
2个回答
0
投票

这里讨论:https://github.com/benoitc/gunicorn/issues/1923 他们提出了 2 个解决方案:

  1. 通过
    --threads 2
    或更高级别至
    gunicorn
  2. 通过
    --preload
    旗帜 对我来说,第一个解决方案有效。我还没试过第二个。

0
投票

我猜问题是你有一个工作人员正在做一项“繁重的工作”,其时间超过了默认的工作人员超时时间。

所以你需要:

  • 例如通过
    CMD gunicorn --timeout 1000 ...
  • 指定超时
  • 添加更多的gunicorn工人,以便能够并行处理超过1个请求

我还建议使用 FastAPI(和

async
路由器)而不是同步烧瓶

© www.soinside.com 2019 - 2024. All rights reserved.