google-cloud-platform - 在到达截止确认时间之前,Google Cloud PubSub 消息多次传递
问题描述
背景:我们配置了云发布订阅主题以在多个应用引擎服务中进行交互,我们在那里配置了基于推送的订阅者。我们已将其确认截止时间配置为 600 秒
问题:我们观察到 pubsub 向其订阅者推送了两次相同的消息(来自其他主题的两次以上),查看日志我可以看到此消息推送发生的时间间隔仅为 1 秒,理想情况下,我们已将 ackDeadline 配置为600 秒,pubsub 应仅在 600 秒后重新尝试消息传递。
需要以下答案:
为什么同一条消息仅在 1 秒内发送了多次
在重新尝试消息传递之前,pubsub 是否不遵守 ackDeadline 配置?
解决方案
消息重新传递可能有几个原因。首先,一条消息可能被发布了两次。有时发布者会收到一个错误,比如超过了最后期限,这意味着发布的时间比预期的要长。在这种情况下,消息实际上可能已经发布,也可能未发布。通常,正确的操作是让发布者重试发布,事实上,这是 Google 提供的客户端库默认执行的操作。因此,可能有两个成功发布的消息副本,即使客户端只获得了其中一个的确认。
其次,Google Cloud Pub/Sub 保证至少一次交付。这意味着偶尔可以重新传递消息,即使 ackDeadline 尚未过去或 ack 已发送回服务。确认是尽力而为,并且大多数情况下,它们会被服务成功处理。但是,由于网络故障、服务器重启和其他类似性质的常规事件,有时订阅者发送的确认不会被处理,从而导致消息重新传递。
订阅者应该被设计成对这些偶尔的重新传递具有弹性,通常通过确保操作是幂等的,即多次处理消息的结果是相同的,或者通过跟踪和捕获重复。或者,可以使用Cloud Dataflow作为订阅者来删除重复项。
推荐阅读
- google-app-engine - 带有 Hydra Docker 映像和 Cloud SQL 代理的 Google App Engine 无法正常工作
- asp.net-mvc - 具有 .Net 4.7 MVC 身份问题的实体框架核心
- python - 通过 os.system('') 激活 VT100?
- go - 什么是 locationName 标签以及如何使用它们?
- kdb - 按列传递多个函数参数 kdb q
- python - 如何在 TensorFlow 中连接大小不等的张量?
- scala - 如何将 ScalaFXML 与 Gradle 结合起来?
- php - 当链接包含特定字符串时如何使用正则表达式?
- javascript - 在 url 中搜索查询
- json - 使用 go-jsonnet 返回纯 JSON