java - Google PubSub 和来自 TOPIC 的重复消息
问题描述
如何防止 Google Cloud PubSub 中发生重复的 msg?
说,我有一个处理它订阅的味精的代码。
说,我有 2 个节点具有相同的服务,具有此代码。
一旦一个人收到了消息但尚未确认,另一个节点将收到相同的消息。这就是我们有两个重复的 msgs的问题所在。
void messageReceiver(PubsubMessage pubsubMessage, AckReplyConsumer ackReply) {
submitHandler.handle(toMessage(pubsubMessage))
.doOnSuccess((response) -> {
log.info("Acknowledging the successfully processed message id: {}, response {}", pubsubMessage.getMessageId(), response);
ackReply.ack(); // <---- acknowledged
})
.doOnError((e) -> {
log.error("Not acknowledging due to an exception", e);
ackReply.nack();
})
.doOnTerminate(span::finish)
.subscribe();
}
解决方案是什么?这是正常行为吗?
解决方案
Google Cloud Pub/Sub 使用“至少一次”交付。从文档:
通常,Cloud Pub/Sub 会按照发布的顺序交付每条消息一次。但是,有时可能会乱序或多次传递消息。通常,容纳多次传递要求您的订阅者在处理消息时是幂等的。
这意味着它保证它将以 1:N 的方式传递消息,因此如果您不通过其他方式首先对其进行重复数据删除,则您可能会多次获取该消息。您无法定义一个设置来保证一次交付。文档确实引用了您可以使用 Cloud Dataflow 获得所需的行为PubSubIO
,但该解决方案似乎已被弃用:
您可以使用 Cloud Dataflow 实现对 Cloud Pub/Sub 消息流的一次性处理
PubsubIO
。PubsubIO 对自定义消息标识符或 Cloud Pub/Sub 分配的消息进行重复数据删除。
说了这么多,我实际上从未见过 Google Cloud Pub/Sub 两次发送消息。您确定这确实是您遇到的问题,还是因为您没有在确认截止日期内确认消息而重新发出消息(如上所述,这默认为 10 秒)。如果您不承认,它将重新发布。从文档 (强调我的):
为单个主题创建订阅。它有几个属性可以在创建时设置或稍后更新,包括:
- 确认截止日期:如果您的代码在截止日期之前未确认消息,则会再次发送消息。默认值为 10 秒。您可以指定的最大自定义期限为 600 秒(10 分钟)。
如果是这种情况,只需在截止日期内确认您的消息,您就不会经常看到这些重复的消息。
推荐阅读
- sql-server - Azure 上的 .net core MVC 应用程序:如何限制访问
- iphone - iPhoneXR Safari 浏览器上的模糊事件
- html - Ionic 3 中的滑动卡片
- javascript - 如何将文本响应评估为 Javascript/React 中的代码
- reactjs - 需要澄清 React 的 JSX 语法
- python - Why is the Average Precision of my TensorFlow model -1.000?
- c# - 远程调试 WinForms 应用程序
- delphi - 在哪里为动态包使用的 DLL 调用 FreeLibrary?
- ios - Crash on Canvas SwiftUI
- python - 如何为每个请求/URL 保存一个输出文件?