Cloud PubSub 重复消息触发的 Cloud Functions

Posted

技术标签:

【中文标题】Cloud PubSub 重复消息触发的 Cloud Functions【英文标题】:Cloud Functions triggered by Cloud PubSub duplicate messages 【发布时间】:2019-10-05 05:28:08 【问题描述】:

我正在尝试将 Cloud Functions 用作由 PubSub 触发的异步后台工作程序,并做一些更长的工作(以分钟为单位)。 完整代码在这里https://github.com/zdenulo/cloud-functions-pubsub

我的原型将数据插入 BigQuery 并等待几分钟(模拟更长的任务)。 我正在向 PubSub 主题发布 100 条消息(间隔 1 秒)。

强调 PubSub 可以多次传递相同的消息,但令我惊讶的是,100 条消息中有 10 到 40 条是重复的。 CF 的响应时间为 5、6、7 分钟。对于 4 分钟的响应,我没有注意到重复。 我在相同的时间间隔内进行了多次测试。接收第一条和第二条消息之间的时间差范围从 ~30 到 ~600 秒。

在文档 https://cloud.google.com/pubsub/docs/troubleshooting 中提到“Cloud Pub/Sub 可以发送重复的消息。例如,当您在消息的确认截止日期到期之前未确认消息时,Cloud Pub/Sub 会重新发送消息。”对于 Cloud Functions 订阅,确认截止日期为 600 秒(10 分钟),因此根据我的理解,这不应该是原因。

也许我的测试用例是特定的,或者可能有其他东西。 对于如何处理这种情况以及这是否正常或如何防止重复(不包括数据流),我将不胜感激。

【问题讨论】:

云函数也可以为任何类型的触发器复制事件,因此您的函数确实应该期望通过幂等接收重复事件。 所有触发器 除了 HTTP 触发器。与explained in the docs 一样,HTTP 函数最多 被调用一次,而后台函数(pubsub 或任何其他触发器)至少 被调用一次。 感谢 cmets 和澄清。 这里有一个很好的评论 - cloud.google.com/pubsub/docs/faq - 标题为“如何检测重复消息?”。我认为一种常见的技术是使用廉价的全局数据存储(redis/memcache)并保存处理的每条消息的 message_id。在处理新消息之前,请检查您之前是否在缓存中没有看到它。 谢谢,@Kolban。 Redis/memcache 方法应该可以工作,但是对于不频繁、少量使用的情况,这可能有点矫枉过正。它总是取决于我猜的用例。我很惊讶我看到了高比例的重复。 【参考方案1】:

存在影响 2019 年 1 月之前部署的 Cloud Functions 的问题,该问题会导致运行时间超过 5 分钟的函数的重复触发器率增加。请尝试删除并重新部署您的函数以解决问题。

【讨论】:

感谢您的评论。该功能是几天前部署的。无论如何,由于 Cloud Tasks 现在支持 Cloud Functions 作为任务工作者,因此这种方法更适合我的情况。

以上是关于Cloud PubSub 重复消息触发的 Cloud Functions的主要内容,如果未能解决你的问题,请参考以下文章

从 Memorystore Redis PubSub 消息触发 Cloud Run API

如何使用消息排序部署 pubsub 触发的云功能?

“请求被中止,因为没有可用的实例” - Google Cloud Functions(PubSub 触发器)

如何使用 Node.js 控制 Cloud PubSub 中的确认

来自 PubSub 主题的 Google Cloud 函数触发器是订阅吗

由 Pub Sub 触发的 Cloud Function 未发布预期消息