Google 云 运行 - 执行始终分配的后台作业 CPU

Google Cloud Run - Executing background job with always-allocated CPU

我在 Cloud 运行 中有一个 Web 应用程序和一个后台工作者服务 运行。
主应用程序调用后台工作程序,它本质上只是一个包裹在薄 Flask 应用程序中的 rq 工作程序,以遵守运行时合同。 rq worker 是通过 subprocess.Popen.
生成的 我不会用 Popen 调用阻塞主线程,return 会立即响应。但是,实例似乎在处理 15 分钟后仍然死亡。

根据文档,只要正在进行某种 CPU 处理(尚不完全清楚),似乎就应该支持此工作流程:

If you want to support background activities in your Cloud Run service, set your Cloud Run service CPU to be always allocated so you can run background activities outside of requests and still have CPU access.

另一篇文章说:

Note that even if CPU is always allocated, Cloud Run autoscaling is still in effect, and may terminate container instances if they aren't needed to handle incoming traffic. An instance will never stay idle for more than 15 minutes after processing a request unless it is kept active using minimum instances.

这个 15 分钟的限制似乎是我遇到的,尽管 CPU 在任何意义上都不是“空闲”。

在某些极端情况下,我生成的特定后台作业可能需要 1 - 2 小时,因此阻塞主线程、return在完成之前不响应,并且增加请求超时是行不通的最多 1 小时(更不用说它容易出错)。

有没有办法在不转向 GKE 或 hacky Cloud Build 解决方法的情况下使这项工作正常进行?

编辑 - 一些额外的细节

工作器服务配置:

这是生成 rq worker 的服务器:

import os
import subprocess

from flask import Flask, Response
from http import HTTPStatus

app = Flask(__name__)

@app.route("/")
def index():
    subprocess.Popen(["rq", "worker", "--burst", "--url", os.getenv("REDIS_URL"), "queue"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    return Response(status=HTTPStatus.OK)

Dockerfile 设置后只运行以下命令:

gunicorn -w 1 --timeout 0 -b 0.0.0.0:8080 app:app

日志没有产生任何特别有用的东西,因为我从不使用 communicate() 或检查 Popen 调用的输出以避免阻塞主线程。结果我只剩下 gunicorn 日志,这并不理想:

使用 gunicorn --timeout 0 并阻塞线程以避免发送 HTTP 响应最多可处理 60 分钟的处理时间(即 Cloud 运行 允许的最高请求超时)。您必须在 Cloud 运行 上配置此设置,因为默认值为 5 分钟。

虽然这不是一个理想的解决方案:

The longer the timeout is, the more likely the connection can be lost due to failures on the client side or the Cloud Run side. When a client re-connects, a new request is initiated and the client isn't guaranteed to connect to the same container instance of the service.

https://cloud.google.com/run/docs/configuring/request-timeout

否则,GKE 或 Compute Engine 会处理此类工作负载。