【发布时间】:2022-01-25 09:27:23
【问题描述】:
情况: 我试图让 Pub/Sub 中的一条消息由 Cloud Run 的 1 个实例处理。其他消息将由另一个 Cloud Run 实例处理。每条消息都会触发在 Cloud Run 实例中运行大约 100 秒的繁重计算。
目前,Cloud Run 配置为最大并发请求数 = 1,最小/最大实例数为 0/5。订阅设置为允许 600 秒的 Ack 截止日期。
问题: 每条消息似乎都在触发多个 Cloud Run 实例启动。我相信这是由于 CPU 利用率高导致 Cloud Run 启动额外的实例来帮助处理。不幸的是,这些新实例试图处理相同的确切消息,导致意外结果。
问题: 有没有办法强制 Cloud Run 只让 1 个实例处理一条消息,而不管 CPU 利用率和其他潜在因素如何?
相关代码片段:
import base64
import json
from fastapi import FastAPI, Request, Response
app = FastAPI()
@app.post("/")
async def handleMessage(request: Request):
envelope = await request.json()
# Basic data validation
if not envelope:
msg = "no Pub/Sub message received"
print(f"error: {msg}")
return Response(content=msg, status_code=400)
if not isinstance(envelope, dict) or "message" not in envelope:
msg = "invalid Pub/Sub message format"
print(f"error: {msg}")
return Response(content=msg, status_code=400)
message = envelope["message"]
if isinstance(message, dict) and "data" in message:
data = json.loads(base64.b64decode(message["data"]).decode("utf-8").strip())
try:
# Do computationally heavy operations here
# Will run for about 100s
return Response(status_code=204)
except Exception as e:
print(e)
谢谢!
【问题讨论】:
-
Cloud Run 进程请求。 PubSub 推送订阅为每条消息创建一个请求。不高的计算,对Cloud Run来说不是问题,因为每个实例只能处理1条消息(并发设置),但是Cloud Run由于当前实例使用情况可以提前启动/预配置其他实例。无论如何,如果你的消息被多次处理,那是因为它不是 CLoud Run 的 Ack。为此返回一个 HTTP 代码 200。如果您这样做,请分享您的代码(仅有用的部分),让我们测试并帮助您
-
我的主要问题是 Cloud Run 的多个实例正在处理相同的消息。我向 Pub/Sub 发送了 2 条消息进行测试,我看到 > 2 个 Cloud Run 实例启动,并且消息处理了 >2 次span>
-
这很奇怪。您是否记录了消息 ID?你确定这是同一条消息吗?
-
我刚做了。通过 Pub/Sub 发送 2 条消息,启动 4 个 Cloud Run 实例。 2 条消息的 messageId 总共记录了 4 次(每个唯一的 messageId 两次)
-
你有多少订阅?
标签: google-cloud-platform google-cloud-pubsub autoscaling google-cloud-run