对于从 PubSub 触发的 Cloud Run,什么时候发送请求消息的 ACK 合适?

问题描述

我正在构建一个Cloud Run 上运行的服务,该服务由 PubSubEventArc 触发。 “PubSub”保证至少交付一次,并且会在每个 ackNowledgement 截止日期重试。此截止日期在队列订阅详细信息中设置。

当服务收到发布-订阅请求(在服务中作为 POST 请求接收)时,我们可以在两个点发送回确认。

  1. 在收到请求后立即开始请求。然后服务将继续按照自己的节奏处理请求。然而,这article指出

在 Cloud Run 上运行的应用完成请求处理后,容器实例对 cpu 的访问将被禁用或受到严重限制。因此,您不应启动在请求处理程序范围之外运行的后台线程或例程。

所以在开始时发送响应可能不是一种选择

  1. 在服务处理请求之后。因此,这意味着,根据服务将执行的操作,我们无法始终预测处理请求需要多长时间。因此,我们无法正确设置确认截止日期,从而导致 PubSub 重试和重复请求。

那么这里的最佳实践是什么?有没有更好的方法来处理这个问题?

解决方法

由于您担心可能无法设置正确的“确认截止日期”,您可以在代码中使用 modify_ack_deadline(),如果进程仍在运行,您可以动态延长截止日期。您可以参考此 document 以获取示例代码实现。

请注意 maximum acknowledgement deadline is 600 seconds。只需确保您在云运行中的处理不超过上述限制。

,

最佳实践通常是在处理完成后确认消息。除了您链接的 Cloud Run 限制之外,请考虑如果端点在收到消息后立即确认消息,然后在处理该消息时发生错误,您的应用程序可能会丢失该消息。

为了尽量减少重复,您可以将确认期限设置为处理时间的上限。 (如果您的端点最终处理消息的速度比这更快,则 ack 截止时间不会对传入消息进行速率限制。)如果 600 秒的截止时间不够,您可以考虑将消息写入某个持久存储,然后确认它。然后,一个单独的 worker 可以异步处理来自持久存储的消息。

,

确认不适用于 Cloud Run,因为确认用于“拉取订阅”,其中进程不断拉取 Cloud PubSub API。

要将事件从 PubSub 获取到 Cloud Run,您可以使用“推送订阅”,即 PubSub 向 Cloud Run 发出 HTTP 请求,然后等待它完成。

在这个推送场景中,PubSub 已经知道它向您发出了一个请求(您收到了事件),因此它不需要关于收到消息的确认。但是,如果您的请求发送了错误的响应代码(例如 http 500),PubSub 将发出另一个重试请求(这可以在推送订阅本身上进行配置)。