Cloud Run:429:请求被中止,因为没有可用的实例

Map*_*SVK 5 google-cloud-platform google-cloud-pubsub google-cloud-tasks google-cloud-run

我们(作为一家公司)每天都会经历巨大的峰值。我们使用 Pub/Sub -> Cloud Run 组合。

我们遇到的问题是,当高流量到来时,Pub/Sub 会尝试同时将消息推送到 Cloud/Run,而无需任何流量控制。结果?

429:由于没有可用实例,请求被中止。

尽管这被标记为警告,但每个 4xx HTTP 响应都会导致消息重试传递。

因此,消息返回队列并等待。如果消息重复此过程并且仍然获取实例,Cloud Run 会再次返回 429,并且消息会发送回队列。此过程重复 x 次(取决于我们在最大传递尝试中设置的值)。之后,消息进入死信队列。

我们希望避免这种情况,最好不要收到任何 429,这样消息就不会来回传输,并且不会最终出现在死信订阅中,因为它不是我们想要的应用程序错误之一保留在那里,而是由 Pub/Sub 不控制流程并与 Cloud Run 协调引起的警告。

Pub/Sub 和推送订阅(Cloud Run 需要使用)都没有任何流量控制功能。


有没有办法控制发送到 Cloud Run 的消息数量以避免收到 429 响应?而且,当 Cloud Run 明显达到实例限制时,为什么 Pub/Sub 还要尝试交付。最好的方法是将消息保留在队列中,直到实例释放为止。


大多数答案可能会建议增加实例的限制。我们已经设置了 1000。这将无法扩展,因为即使我们将限制设置为 1500 并且出现巨大的峰值,我们也会超过限制并再次收到 429 条消息。

我能想到的唯一选择是一些流量控制。到目前为止,我们已经了解了 Cloud Tasks,但我们不确定这是否可以帮助我们。理想情况下,我们不想引入任何新服务,但如果有必要,我们会这样做。

感谢您提供的所有提示和时间!:)

kym*_*kym 2

以下是一些选项:

  1. 使用第一代事件驱动的云函数/sf/answers/5303439011/
  2. 使用云任务进行速率限制。但这样你就不会得到死字
  3. 禁用死信并让 pubsub 不断尝试传递。可能想要设置一个结束条件以避免无限重试循环。还需要设置一些警报以确保消息不会过期(如果服务无法跟上负载)。
  4. 通过跟踪每个 messageId 的尝试计数(IE 使用 Redis)来处理应用程序代码,并在尝试计数超过阈值时发布到死信主题。这很容易抽象,不会引入新服务,并检查所有框,但肯定会增加状态管理的开销。