如果响应不成功,Pub/Sub 是否立即重新发送消息?

Does Pub/Sub immediately resend a message in case of a non-success response?

我有一个订阅了 Pub/Sub 主题的 Cloud Function。

根据docs,如果云函数returns没有成功响应,它将重新发送消息:

The endpoint acknowledges the message by returning an HTTP success status code. A non-success response indicates that the message should be resent.

我的问题是:如果回复不成功,消息会立即重发还是Pub/Sub会遵守确认期限重发消息?

更新:

我认为这个问题没有意义,我会解释原因。

由于您无法访问 Pub/Sub 函数中的 Response 对象,因此无法直接发送响应代码(我对此不太确定,所以请纠正我,如果我错了)。

因此,非成功响应只能由以下原因引起:

  1. timeout,这是以确认截止时间为准,所以在这种情况下确认截止时间显然是要遵守的。

  2. An error in the Cloud Function, and as 表示,默认情况下 Pub/Sub 甚至不会重试,所以关心确认截止日期是没有意义的。

Cloud Functions 依赖于 Cloud Pub/Sub 推送交付以触发执行。系统传递并发消息的速率继续加倍,直到出现传递失败或系统达到配额或资源限制。每次发送失败,端点的并发请求数减半。

Cloud Pub/Sub 但是,如果 non-ok 状态明确取消消息,则不会等到 ack 过期截止日期才重新发送消息。相反,它会暂时 back-off 推送消息。在多次传送失败后,您可以预计此延迟大约为几秒。

您可以详细了解配额和送达率 here

在调查 Google Cloud Functions 行为时,我发现如果 Cloud Functions 失败并以错误消息响应,它不会重试该操作。我创建了一个云函数,它将由 Pub/Sub 事件触发,然后以错误消息响应。该消息已记录在 Stackdriver 日志记录页面中,然后也记录了错误,但该函数从未重新发送该消息,因此它从未被重新触发。在那之后,我还尝试在实际读取 Pub/Sub 的消息之前用错误代码进行响应,它在日志中仍然失败但从未重新发送消息以再次实际重试其操作。

这是 Google Cloud Function 保护自己免受无限循环中 运行 影响的预期行为。如果基于 Pub/Sub 主题事件触发的 Cloud Function 失败,它很可能会在重试期间再次失败。因此,如果它一直调用自己,向主题重新发送消息,它也会陷入循环,产生计费成本。

要使用 Google Cloud Functions 的重试功能,您必须在部署时使用标志启用它。有关详细信息,您可以在 Retrying Background Functions 文档中查看。根据您将在 Google Cloud Function 重试策略的配置中设置的内容,它将触发重试。

但是,重试将立即进行,并且不会遵守确认截止日期。

更新

使用 Pub/Sub 事件触发器创建 Google 云函数时,会为所选主题创建订阅,您可以在主题的详细信息页面中看到这一点 (Google Cloud Platform > Pub/Sub > Topics > [TOPIC_NAME]) .订阅负责读取主题中发布的消息,并将 ack 发送回主题。一个主题可以有多个订阅,并且它至少向每个订阅发送一次接收到的消息。正如 Subscriber overview 文档中所述。

在同一个link中表示A message is considered outstanding once it has been sent out for delivery and before a subscriber acknowledges it.。还表示The subscriber has a configurable, limited amount of time -- known as the ackDeadline -- to acknowledge the outstanding message.。为了进一步详细说明该系统的工作原理,假设有一个 TopicA,然后是 SubscriberA 和 SubscriberB 订阅了该主题。现在,正在向 TopicA 发送消息,因此 TopicA 将消息转发给 Subscriber-ASubscriber-B 并开始等待来自两个订阅者的确认。每个订阅者都有不同的 ack 响应时间,即 ackDeadline。如果 SubscirberA 以 ack 响应,TopicA 将继续等待 Subscriber-B。如果 Subscriber-B 未在指定时间内发送确认,则 Topic-A 将仅向 Subscriber-B.

重新发送消息

现在,您已经提到了文档的 The endpoint acknowledges the message by returning an HTTP success status code. A non-success response indicates that the message should be resent. 部分。这部分讨论的是订阅者的响应,而不是 Google Cloud Functions 的响应。由于 Google Cloud Functions 由于消息在主题中发布而被调用,从那时起与该 Cloud Functions 关联的订阅者将向主题发送回确认消息。之后,无论 Google Cloud Function 是否处理消息失败,它都不会以任何方式影响 Pub/Sub 主题,因为它只关心已经传递的消息。

进一步阐述问题更新部分中的两点:

  1. 如果Google Cloud Function 将被执行,这意味着ack 消息已经被发​​送回主题。想象一下,有一个订阅者将 ack 响应时间设置为 10 秒,而 Cloud Function 需要 5 分钟才能超时。显然,当订阅者的10秒已经过去时,它不会再等待4分50秒让Cloud Function超时。因此,这意味着 Google 云函数一被调用,订阅者就已经发送了 ack。
  2. 我在第一个回复中提到的错误是 Google Cloud Function 的错误。因此,如果您的 Cloud Function 无法处理接收到的消息,您将必须实施重试方法,该方法将重试特定次数,然后停止以避免循环。但是,主题已经被告知消息已传递给订阅者,因此在开始执行 Cloud Function 时已经发送了确认。