Cloud Pub/Sub 在回调中缺少 ack/nack 不会导致重新传送

Cloud Pub/Sub missing ack/nack in callback not causing redelivery

我正在努力确保如果没有 ack/nack 发送,Cloud Pub/Sub 将重新传送我的消息。即使我等待超过 10 分钟,它似乎也没有这样做,这应该是 Acknowledgment Deadline 的最长时间。

我使用此处的示例作为起点: https://cloud.google.com/pubsub/docs/quickstart-py-mac

基本上,我在回调函数中注释了确认消息的行。我使用了两个终端,一个用于发布消息,一个用于作为订阅者接收消息。由于没有发送任何 ack,我希望 Cloud Pub/Sub 尝试在 ack 截止日期内的某个时间将消息重新发送给订阅者,但事实并非如此。

这里的文档

https://godoc.org/cloud.google.com/go/pubsub#hdr-Deadlines

说 "ACK deadlines are extended periodically by the client... up to 10 minutes",所以我等了 10 分钟以防确认截止日期延长到该最大值,但我仍然没有收到重新发送的消息。

这是我使用的编辑后的回调方法。这是我对示例代码所做的唯一更改。

def callback(message):
        print('Received message {} of message ID {}'.format(
            message, message.message_id))
        # Acknowledge the message. Unack'ed messages will be redelivered.
        # message.ack()
        print('Acknowledged message of message ID {}\n'.format(
            message.message_id))

如果我终止订阅者 (sub.py) 并重新启动它,消息将重新传送。难道我做错了什么?此外,当我发送 Nack 而不是根本不发送任何内容时,消息会很快重新传送。

编辑:

上好像有人问过类似的问题

https://github.com/googleapis/google-cloud-python/issues/5005

https://github.com/googleapis/google-cloud-python/issues/5044

我想确认的事情:

  1. 订阅中设置的 Ack Deadline 并不总是使用的值。 Pub/Sub 认为有必要对其进行扩展。

  2. 10 分钟的最长 Ack Deadline 实际上并不是重新发送消息之前可以经过的最长时间

  3. 此最长时间由 flow_control.max_lease_duration 变量决定(默认为 2 小时)

ackDeadline 是一条消息在没有 ack、nack 或 modAckDeadline 的情况下可以发送给订阅者的最长时间。一旦这段时间过去,该消息就成为重新传递的候选者,尽管重新传递可能不是立即的。此字段的最大值为十分钟。

云 Pub/Sub 客户端库在收到消息后,会自动发送消息的 modAckDeadline 请求,直到它被确认、取消或 flow_control.max_lease_duration 时间段过去。本质上,它延长了确认期限。目标是让客户端库跟踪 ack 截止日期并根据需要自行扩展消息,这样用户就不必这样做了。

这就是您看到客户端库行为与订阅上配置的 ackDeadline 之间存在差异的原因。使用客户端库时,您应该将 max_lease_duration 设置为您希望消息对订阅者有效的最长时间。