我正在开发一个发布/订阅系统,我需要确保消息按照发布的确切顺序接收,即使使用多个排序键也是如此。我的系统发布大量消息,可能跨越各种主题和排序键,但对于应用程序逻辑来说,按照发送顺序处理这些消息至关重要。
我使用 Google Cloud Pub/Sub 实现了一个 Pub/Sub 模型,使用排序键来确保具有相同键的消息按顺序处理。这是我的发布逻辑的简化版本:
Publisher publisher = Publisher.newBuilder(topicName).build();
String[] orderingKeys = {"OrderKey1", "OrderKey2", "OrderKey3"}; // Multiple ordering keys
for (String orderingKey : orderingKeys) {
for (int i = 1; i <= 500; i++) { // Publish 500 messages for each ordering key
String messageStr = "Message " + i + " for " + orderingKey;
ByteString data = ByteString.copyFromUtf8(messageStr);
PubsubMessage pubsubMessage = PubsubMessage.newBuilder()
.setData(data)
.setOrderingKey(orderingKey)
.build();
ApiFuture<String> future = publisher.publish(pubsubMessage);
System.out.println("Published message ID: " + future.get());
}
}
我的订阅者只需在消息进来时确认消息,并打印出其内容。
尽管排序键确保具有相同键的消息被排序,但我面临着一个问题,即来自不同排序键的消息没有按照发布的顺序接收。例如,我可能会按以下顺序收到消息:
Received message: Message 1 for OrderKey1 Received message: Message 2 for OrderKey1 Received message: Message 1 for OrderKey2 Received message: Message 3 for OrderKey1 Received message: Message 2 for OrderKey2
这对于我的用例来说是有问题的,因为我需要完全按照消息发布的顺序处理消息,而不管排序键如何。
我正在寻找一种解决方案或设计模式,使我能够跨多个排序键维护消息的全局排序。理想情况下,消息应该按照发布者发布的确切顺序接收和处理,无论使用什么排序键。
有没有办法在 Google Cloud Pub/Sub 中实现此目的,或者我应该考虑替代方法或解决方案来满足此要求?
如果您试图维护所有消息的全局排序,那么对键进行排序并不是一个好的选择,因为正如您所观察到的,顺序只能在键内保证,而不能在键之间保证。如果您希望使用 Pub/Sub 进行总排序,则需要使用类似 Dataflow windowing 的功能来发出按发布时间分组在有序时间窗口中的消息。请注意,如果您使用 Dataflow,则不应使用排序键,因为它会干扰 Dataflow 的窗口。