在确认过之后,仍会不断收到来自Google Pub/Sub订阅的消息[Heisenbug]。

8
我想指出的是,我将要描述的情况很少发生,在大多数情况下一切都按预期工作。
我的java应用程序在Pub/Sub端有1个主题和1个订阅。应用程序监听订阅,进行一些处理并发送确认回复。由于Google Pub/Sub保证至少传递一次消息,我们在我们这一端基于“objectGeneration”头和“objectId”头进行消息去重。
有时候我们会看到被确认的消息被我们的应用程序再次接受,这是意外的行为。
日志示例:
//first
2019-12-17 20:51:57.375 INFO 1 --- [sub-subscriber3] bucketNotificationFlow : Received new message from pub-sub: GenericMessage [payload={....}, headers={.....objectGeneration=1576615916875106, eventTime=2019-12-17T20:51:56.874940Z, objectId=Small_files_bunch/100_12_1.csv, ....
....
2019-12-17 20:51:57.698 INFO 1 --- [sub-subscriber3] .i.g.PubSubMessageAcknowledgementHandler : Acknowledged message - 1576615916875106
...
//duplicate 1
2019-12-17 20:51:59.663 INFO 1 --- [sub-subscriber4] bucketNotificationFlow : Received new message from pub-sub: GenericMessage [payload={...}, headers={ objectGeneration=1576615916875106, eventTime=2019-12-17T20:51:56.874940Z, objectId=Small_files_bunch/100_12_1.csv", ....
...
2019-12-17 20:51:59.704 INFO 1 --- [sub-subscriber4] c.b.m.i.DiscardedMessagesHandler : Duplicate message received GenericMessage [ headers={idempotent.keys=[objectGeneration.1576615916875106, objectId.Small_files_bunch/100_12_1.csv], ...
....
//duplicate 2
2019-12-17 22:52:02.239 INFO 1 --- [sub-subscriber1] bucketNotificationFlow : Received new message from pub-sub: GenericMessage [payload={...}, headers={objectGeneration=1576615916875106, eventTime=2019-12-17T20:51:56.874940Z, objectId=Small_files_bunch/100_12_1.csv, ...
...
2019-12-17 22:52:02.339 INFO 1 --- [sub-subscriber1] c.b.m.i.DiscardedMessagesHandler : Duplicate message received GenericMessage [ headers={idempotent.keys=[objectGeneration.1576615916875106, objectId.Small_files_bunch/100_12_1.csv], ...

// and so on each 2 hours

确认码的代码:

var generation = message.getHeaders().get("objectGeneration");
pubSubMessage = message.getHeaders().get(GcpPubSubHeaders.ORIGINAL_MESSAGE, BasicAcknowledgeablePubsubMessage.class)
pubSubMessage.ack().addCallback(
        v -> {
            removeFromIdempotentStore(targetMessage, false);
            log.info("Acknowledged message - {}", generation); //from logs we see that this line was invoked
        },
        e -> {
            removeFromIdempotentStore(targetMessage, false);
            log.error("Failed to acknowledge message - {}", generation, e);
        }
);

GCP订阅页面包含以下图表: enter image description here StackDriver确认图表: enter image description here 有什么想法是怎么回事,如何进行故障排除和修复?
2个回答

1

请尝试检查Stackdriver以查看您是否错过确认截止时间

两个重复之间的等待时间非常有趣。您是否尝试过扩展消息截止时间?(有关此信息,请参见上面的链接。)


为什么是2小时?因为我设置了max-ack-extension-period: 7200 - gstackoverflow
确认截止时间为600秒。 - gstackoverflow
你是否检查了Stackdriver日志,以查看您是否错过了确认截止日期? - Maximus Macdonald
http://dl3.joxi.net/drive/2019/12/27/0005/3037/338909/09/bda03c0e46.jpg - gstackoverflow
你有任何想法吗? - gstackoverflow
显示剩余10条评论

0

在此处查看更多信息:如何清理JdbcMetadataStore?

根据我们的结论,最好不要立即从元数据存储表中删除条目。一些外部作业应该定期执行清理操作,只针对那些足够旧且我们确信Pub/Sub不会再次向我们重新投递相同消息的条目。


是的,这是我目前的情况。但我认为这只是一个解决方法。我想我可能配置了错误的Google Pub/Sub或Spring Cloud GCP。虽然可能性很小,但这可能是库或Pub/Sub中的错误。重新传递是可以的,并且是预期的异常情况。但在我们的情况下,成功的回调被调用,但消息没有从订阅中删除,我们一遍又一遍地收到它。因此,我们不能忽略重复的消息,我们必须重复确认以将消息从订阅中删除。 - gstackoverflow
"again and again" 意味着无尽。 - gstackoverflow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接