【问题标题】:"[CRITICAL] WORKER TIMEOUT" in logs when running "Hello Cloud Run with Python" from GCP Setup Docs从 GCP 设置文档运行“Hello Cloud Run with Python”时,日志中出现“[CRITICAL] WORKER TIMEOUT”
【发布时间】:2020-06-17 15:34:51
【问题描述】:

按照tutorial here,我有以下2个文件:

app.py

from flask import Flask, request

app = Flask(__name__)


@app.route('/', methods=['GET'])
def hello():
    """Return a friendly HTTP greeting."""
    who = request.args.get('who', 'World')
    return f'Hello {who}!\n'


if __name__ == '__main__':
    # Used when running locally only. When deploying to Cloud Run,
    # a webserver process such as Gunicorn will serve the app.
    app.run(host='localhost', port=8080, debug=True)

Dockerfile

# Use an official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.7-slim

# Install production dependencies.
RUN pip install Flask gunicorn

# Copy local code to the container image.
WORKDIR /app
COPY . .

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 app:app

然后我使用 Cloud Build 和 Cloud Run 构建并运行它们:

PROJECT_ID=$(gcloud config get-value project)
DOCKER_IMG="gcr.io/$PROJECT_ID/helloworld-python"
gcloud builds submit --tag $DOCKER_IMG
gcloud run deploy --image $DOCKER_IMG --platform managed

代码似乎运行良好,我可以通过给定的 URL 访问应用程序。但是,日志似乎表明存在严重错误,并且工作人员不断重新启动。这是启动应用程序并在我的网络浏览器中发出一些请求后来自 Cloud Run 的日志文件:

2020-03-05T03:37:39.392Z Cloud Run CreateService helloworld-python ...
2020-03-05T03:38:03.285477Z[2020-03-05 03:38:03 +0000] [1] [INFO] Starting gunicorn 20.0.4
2020-03-05T03:38:03.287294Z[2020-03-05 03:38:03 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)
2020-03-05T03:38:03.287362Z[2020-03-05 03:38:03 +0000] [1] [INFO] Using worker: threads
2020-03-05T03:38:03.318392Z[2020-03-05 03:38:03 +0000] [4] [INFO] Booting worker with pid: 4
2020-03-05T03:38:15.057898Z[2020-03-05 03:38:15 +0000] [1] [INFO] Starting gunicorn 20.0.4
2020-03-05T03:38:15.059571Z[2020-03-05 03:38:15 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)
2020-03-05T03:38:15.059609Z[2020-03-05 03:38:15 +0000] [1] [INFO] Using worker: threads
2020-03-05T03:38:15.099443Z[2020-03-05 03:38:15 +0000] [4] [INFO] Booting worker with pid: 4
2020-03-05T03:38:16.320286ZGET200 297 B 2.9 s Safari 13  https://helloworld-python-xhd7w5igiq-ue.a.run.app/
2020-03-05T03:38:16.489044ZGET404 508 B 6 ms Safari 13  https://helloworld-python-xhd7w5igiq-ue.a.run.app/favicon.ico
2020-03-05T03:38:21.575528ZGET200 288 B 6 ms Safari 13  https://helloworld-python-xhd7w5igiq-ue.a.run.app/
2020-03-05T03:38:27.000761ZGET200 285 B 5 ms Safari 13  https://helloworld-python-xhd7w5igiq-ue.a.run.app/?who=me
2020-03-05T03:38:27.347258ZGET404 508 B 13 ms Safari 13  https://helloworld-python-xhd7w5igiq-ue.a.run.app/favicon.ico
2020-03-05T03:38:34.802266Z[2020-03-05 03:38:34 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:4)
2020-03-05T03:38:35.302340Z[2020-03-05 03:38:35 +0000] [4] [INFO] Worker exiting (pid: 4)
2020-03-05T03:38:48.803505Z[2020-03-05 03:38:48 +0000] [5] [INFO] Booting worker with pid: 5
2020-03-05T03:39:10.202062Z[2020-03-05 03:39:09 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:5)
2020-03-05T03:39:10.702339Z[2020-03-05 03:39:10 +0000] [5] [INFO] Worker exiting (pid: 5)
2020-03-05T03:39:18.801194Z[2020-03-05 03:39:18 +0000] [6] [INFO] Booting worker with pid: 6

请注意日志末尾的工作线程超时和重启。它是一个严重错误的事实让我认为它不应该发生。这是预期的行为吗?这是 Cloud Run 机器在请求来来去去时启动和停止我的服务的副作用吗?

【问题讨论】:

  • 我不确定为什么会这样。 1) Cloud Run 不支持后台线程。在 HTTP 请求之间,任何线程都将 CPU 空闲到 0,这将导致 TCP 连接等失败。 2)你不需要gunicorn。您可以在 Dockerfile 中简单地使用 CMD [ "python", "app.py" ]
  • 对于 app.py,从环境中读取端口号,如下所示:app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080))
  • @JohnHanley 我的印象是你应该只使用内置的烧瓶服务器进行开发,而不是生产。
  • Cloud Run 也是如此。 Werkzeug(内置的 Flask HTTP 服务器)不适合生产使用。

标签: python flask google-cloud-platform gunicorn google-cloud-run


【解决方案1】:

这是一个在 Cloud 上运行的 Flask 应用程序的工作示例。我的猜测是你的最后一行或 Decker 文件和你的 python 文件的最后一部分是导致这种行为的原因。

ma​​in.py

# main.py
#gcloud beta run services replace service.yaml


from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():

        msg = "Hello World"
    return msg

Dockerfile(不需要apt-get部分)

# Use the official Python image.
# https://hub.docker.com/_/python
FROM python:3.7

# Install manually all the missing libraries
RUN apt-get update
RUN apt-get install -y gconf-service libasound2 libatk1.0-0 libcairo2 libcups2 libfontconfig1 libgdk-pixbuf2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libxss1 fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils

# Install Python dependencies.
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . .

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 main:app

然后构建使用:

gcloud builds submit --tag gcr.io/[PROJECT]/[MY_SERVICE]

并部署:

gcloud beta run deploy [MY_SERVICE] --image gcr.io/[PROJECT]/[MY_SERVICE] --region europe-west1 --platform managed

更新 我再次检查了您提供的日志。 在新部署后开始出现这种警告/错误是正常的,因为您的旧实例没有处理任何请求,而是在那时它们处于空闲状态,直到它们完全关闭。

Gunicorn 的默认超时时间也为 30 秒,这与“引导工作程序”的时间和您看到错误之间的时间相匹配。

【讨论】:

  • 我也收到了[CRITICAL] WORKER TIMEOUT 以及您的代码。
  • 我尝试启动一项全新的服务,这样它就不会关闭任何旧实例,但我仍然遇到超时。
【解决方案2】:

Cloud Run 已缩减您的一个实例,gunicorn 仲裁者认为它已停止。

您应该将 --timeout 0 添加到您的 gunicorn 调用中以完全禁用工作器超时,这对于 Cloud Run 来说是不必要的。

【讨论】:

  • --preload 选项似乎已经解决了这个问题。最简单的烧瓶应用程序怎么可能启动时间太长?您是否知道使用 --preload 选项时的任何权衡,或者我应该注意的任何其他注意事项?
  • 这可能是 Gunicorn 如何解释停滞的工作人员和 Cloud Run 的运行时的问题,看起来应用程序实际上并没有花那么长时间才能启动。这里列出了权衡:docs.gunicorn.org/en/stable/settings.html#preload-app
  • 谢谢。我接受了您的回答,因为 --preload 选项似乎对我有用。
【解决方案3】:

我在 heroku 上遇到了错误 [11229] [CRITICAL] WORKER TIMEOUT (pid:11232) 我把我的 Procfile 改成了这个

web: gunicorn --workers=3 app:app --timeout 200 --log-file -

它通过增加--timeout 解决了我的问题

【讨论】:

    猜你喜欢
    • 2020-03-29
    • 2020-01-07
    • 1970-01-01
    • 2018-04-23
    • 2017-10-18
    • 2021-03-03
    • 2021-06-12
    • 2020-08-19
    • 1970-01-01
    相关资源
    最近更新 更多