我有一个 PubSub 订阅,启用了一次性传送和指数重试。指数重试的最小退避时间为 10 秒,最大退避时间为 600 秒。 ack 截止时间设置为 60 秒(在第二次测试中也设置为 120 秒)。
我有一位订阅者正在阅读此订阅内容
Subscriber subscriber = pubSubTemplate.subscribe("projects/PROJECT_ID/subscriptions/sushil-exactly-once-topic-sub", (basicAcknowledgeablePubsubMessage -> {
PubsubMessage message = basicAcknowledgeablePubsubMessage.getPubsubMessage();
String data = message.getData().toStringUtf8();
String id = message.getMessageId();
log.info("Message {}", data);
}));
subscriber.startAsync();
我坚决不
acking
我的信息是为了模拟现实世界的失败。我看到的是,第一次重新交付总是在多个测试中一致地发生在 23-26 sec
左右。
2023-07-13T11:22:04.967+05:30 INFO 66438 --- [sub-subscriber1] c.w.e.PubSubStandaloneConfiguration : Message Message-1
2023-07-13T11:22:30.715+05:30 INFO 66438 --- [sub-subscriber1] c.w.e.PubSubStandaloneConfiguration : Message Message-1
2023-07-13T11:23:47.788+05:30 INFO 66438 --- [sub-subscriber2] c.w.e.PubSubStandaloneConfiguration : Message Message-1
首次重新投递后,所有投递均在 60 秒用完后进行。
我已经对
spring-integration
和基本消费者(上面的代码)进行了尝试,并且行为是一致的。
我的理解是,即使是第一次重新交付也应该在 60 秒后发生。
我只是想检查这是否是正确的行为以及我的理解是否有缺陷或者是否存在一些错误?
退避时间是Pubsub在重新发送消息之前等待的时间。如果在连续传送中您的消息未得到确认,则此退避时间将逐渐增加(最多 600 秒)。谷歌文档here中提到了这一点。
我最后复制了这个场景,这就是它的工作原理。考虑到您的设置,确认截止时间为 60 秒,最小退避时间为 10 秒。在您的第一条消息未得到确认(超过 60 秒确认期限)后,pubsub 将等待至少 10 秒来重新传递消息。请注意,有时可能会超过提供的最短退避时间。现在,如果消息没有被确认,pubsub 将再次重新发送,等待时间超过 10 秒。
您是否尝试过在订阅者选项上设置 ackDeadline ?
我刚刚遇到了同样的问题并去看了源代码。 似乎每种语言都有一个默认值,即使使用默认配置,订阅时也会强制执行该默认值,从而覆盖存储桶配置。
例如 对于 Nodejs,订阅者将自动将其设置为 10 秒。
参见 https://github.com/googleapis/nodejs-pubsub/blob/main/src/subscriber.ts#L356
对于 C#,订阅者将自动将其设置为 60 秒。
请参阅 https://github.com/googleapis/google-cloud-dotnet/blob/main/apis/Google.Cloud.PubSub.V1/Google.Cloud.PubSub.V1/SubscriberClient.Settings.cs#L66 和https://github.com/googleapis/google-cloud-dotnet/blob/main/apis/Google.Cloud.PubSub.V1/Google.Cloud.PubSub.V1/SubscriberClient.cs#L77