云 Pub/Sub 订阅者 max_messages 无法使用消息排序

Cloud Pub/Sub subscriber max_messages not working with message ordering

我正在使用 Cloud Pub/Sub 构建作业队列,我希望按照 Pub/Sub 服务接收消息的顺序接收消息。我使用 message ordering enabled. I'm developing my system in Python with the google-cloud-pubsub package. As suggested in this doc 创建了一个主题和一个订阅,我必须使用排序键发布消息。

If messages have the same ordering key and you publish the messages to the same region, subscribers can receive the messages in order.

在订阅端,我需要对消息进行批量处理,所以使用max_messages参数来控制。但是,当我启用消息排序选项时,每次我都无法按预期提取 max_messages 条消息,只能从订阅中提取一条消息。奇怪的是,当我禁用消息排序时,它 returns max_messages 条消息。

出版商代码:

...
topic_path = 'xxx'
ordering_key = '202011240000'
while True:
    job = {'job_id': 'xxxxxx', 'foo': 0, 'bar': 0}
    data = json.dumps(job, default=str).encode('utf-8')
    publisher.publish(topic_path, data=data, ordering_key=ordering_key)
    time.sleep(1)

订阅者代码:

...
subscription_path = 'xxx'
subscriber.pull(request={'subscription': subscription_path, 'max_messages': 300})
...

是我做错了还是Pub/Sub是这样设计的?

max_messages 属性 并不意味着服务器将保证 return 那个数量的消息,即使它们可用。通过有序交付,returned 到单个拉取请求的消息批次将包含最大数量的消息的可能性更小,因为必须进行更多协调以确保消息按顺序发送,特别是如果您使用单个订购代码。服务器尝试不保留等待更多消息发送的请求太长时间,否则端到端延迟可能会变得更加困难。

有两种方法可以解决这个问题。第一个是切换到 Cloud Pub/Sub 客户端库,它使用流式拉取,因此可以更好地在消息可用时立即传递消息,因为存在用于传递消息的持久连接。

第二个是确保你同时有很多优秀的拉动。请注意,这对单个排序键的情况没有帮助,因为排序键的消息列表一次只能是未完成的。如果您有很多订购键,这可能会有所帮助。

有关传递语义的详细信息,请参阅 ordering keys Medium post 的“按顺序接收消息”部分。