Wil*_*rin 5 google-cloud-pubsub google-cloud-functions
有一个 Google Cloud PubSub 主题,我们向其发布 200 万条微小/小型消息。我们设置了一个云函数来处理通过该主题发送的消息。在检查日志时,我们发现许多此类消息被多次处理。总而言之,我们收到的消息数量为 150-200%(请参见最后的屏幕截图)。
问题是:这是为什么?我们如何正确配置事物以减少重复?
1中标记为和。2所以我想绝对确定这是“真正的”重复,我的意思是它是 PubSub 多次传递消息/事件,而不是我们在某个地方笨拙地引入的重复。因此,我修改了函数代码,根据外部消息 ID 形成数据存储区密钥,并context.messageId使用计数器将其写入数据存储区。如果密钥已经存在,则计数器会递增。之后我立即记录该实体。以下是 458,940 次处决的统计数据:
|-------------------|-------------------|
| Counter | Logs |
|-------------------|-------------------|
| 1 | 208,733 |
| 2 | 101,040 |
| 3 | 62,965 |
| 4 | 37,156 |
| 5 | 20,583 |
| >5 | 28,463 |
| >15 | 20 |
| >20 | 0 |
|-------------------|-------------------|
Run Code Online (Sandbox Code Playgroud)
我现在唯一的理论是,重复是由于底层基础设施由于实例限制而响应 429。请参阅以下屏幕截图。
我们不再真正注意到这一点,因为我们只是通过过滤 for 来在日志控制台中过滤出相应的日志消息log_name,因为基础设施抛出大量警告和错误似乎是预期的行为。这就是为什么我也怀疑这是重复的原因。另一方面,在这些情况下,基础设施看起来确实可以发送 NACK。
尽管感觉预期的行为是原始消息的传递失败并返回 429(但不会显示在我们的日志中),然后重新传递,可能会重复。这不是我们所观察到的,我们的日志确实显示重复的执行。
所以我不确定这是否是一个有希望的线索,但这就是我现在所得到的。
我觉得我们所观察到的内容听起来与这个问题和此处的文档中描述的内容相似,但是这是关于“StreamingPull”订阅,而 GCF 托管订阅似乎是(特殊?)“推送”订阅。一开始我很兴奋,因为听起来很相似,但似乎并不适用。
显示主题之间的消息重复的屏幕截图:
订阅配置(由 GCF 管理):
发生429 \xe2\x80\x99s 错误的原因是请求过多或实例流量过多。另外,您的最大实例数为 90,建议默认值为 3000。
\n此外,如果您不想设置任何限制,您可以删除最大实例数或将其设置为 0。另一方面,您可以添加更高的最大实例数(从 90 到 180),最后再稍高一些,以解决 429\xe2\x80\x99s 错误的问题。
\n其他可能导致订阅中出现重复行为的因素包括:
\n订阅者\xe2\x80\x99s 队列中的消息未在截止期限内得到处理和确认;
\n客户端库继续(自动)延长截止时间\n希望最终能够处理这些消息;
\n在某些时候,在多次延长截止日期之后,客户端库\ng放弃了,因此这些消息被丢弃并重新传递;
\nPub/Sub 中的消息是批量投递的,因此不仅过期的消息会被重新投递,属于这些批次的消息也会被重新投递;
\n订阅者的队列将充满重复项,这会减慢\n积压的消耗;
\n由于当前的重复项也会过期并生成新的重复项,因此问题变得越来越严重。
\n| 归档时间: |
|
| 查看次数: |
1158 次 |
| 最近记录: |