我有一个spring服务,用于订阅来自google cloud pubsub(拉)中某个主题的消息。总的来说,它可以正常工作。但是我想对重发的邮件有更多的控制。我的服务有时需要取消整理消息,或者只是让ackDeadline通过,这样我以后才能再次获得该消息。在测试单个消息时,被拒绝的消息几乎立即返回我,而我根本不应答或根本不应答的消息在ackDeadline默认为10秒后返回。我希望推迟重复使用这些消息。我认为重试设置是针对此类情况设计的。 我还应该提到,我目前正在使用模拟器在本地进行测试,并通过代码创建订阅。我正在使用PubSubAdmin进行管理。
根据此docu,我尝试在个人资料配置中设置这些配置。像这样:
spring.cloud.gcp.pubsub.subscriber.retry.initial-retry-delay-second: 4
spring.cloud.gcp.pubsub.subscriber.retry.max-attempts: 5
spring.cloud.gcp.pubsub.subscriber.retry.initial-rpc-timeout-seconds: 4
spring.cloud.gcp.pubsub.subscriber.retry.max-rpc-timeout-seconds: 8
spring.cloud.gcp.pubsub.subscriber.retry.max-retry-delay-seconds: 7
spring.cloud.gcp.pubsub.subscriber.retry.total-timeout-seconds: 3000
,但对重新出现消息的时间没有影响。 我是否错误地理解重试设置的含义?也许它们仅在存在某些连接问题时才生效,而不是在缺少或缺乏确认的情况下生效?还是我必须在使用DeploymentManager创建预订时设置设置,并且不允许通过代码设置它们?或者也许在(开发)配置文件配置中设置它们将不适用于PubSubAdmin? 感谢您的任何建议!
edit:我想在5秒后进行第一次重试,但是在10秒后进行下一次重试,依此类推。此外,我想设置最大重试次数。因此,我不感兴趣的是将ackDeadline设置为更大的数字。
edit2:为什么要破解:其中一项服务(我们称其为网桥)正在订阅消息,必须验证每条消息,如果可以,则将其传递给另一个外部系统。该服务充当该系统的桥梁,因为我们不能直接在第二个系统上工作。在某些情况下,消息需要一些额外的信息,因此网桥将尝试在其他地方获取它(包括很多微服务),有时会发生,此时此刻还没有额外的信息(尚未)。因此,第一个想法是不要确认该消息,然后让它再次出现。但是我不想在接下来的7天内每10秒钟询问一次(使用ackDeadline),我只想尝试几次,如果2小时后还没有出现,它将永远不会出现。因此我们尝试解决问题,希望这些重试设置可以帮助管理重发。但是,因为他们没有这样做,所以我认为唯一的方法是自己构建一些东西来管理桥中的这些消息。也许存储消息ID和重试次数,以便我可以在5次之后确认,然后将消息推送到另一个主题以进行不同的处理。还是有更好的解决方案?
答案 0 :(得分:1)
您可以使用PubSubSubscriberTemplate.modifyAckDeadline()
以编程方式延长通过pull检索的一批消息的截止日期。如果您只需要延长选择的几个散兵的截止日期,则每个AcknowledgeablePubsubMessage
都有一个modifyAckDeadline()
方法。
如果该特定订阅上的所有消息都需要更长的确认时间,则可以在GCP控制台中通过编辑订阅并更新“确认截止日期”字段来设置默认值。
答案 1 :(得分:1)
Cloud Pub / Sub不为特定消息提供指数补偿。一个小窍门只会告诉Cloud Pub / Sub您无法处理该消息。
如果您要记录为什么需要整理邮件,我可以提供一个更有用的答案。如果无法处理当前负载,则可以使用here中所述的流控制选项来减少发送给客户端的未完成消息或字节数。如果您知道有不好的消息,则应该在推送到另一个要处理的死信主题之后再确认它们。
响应编辑2: 如果您遇到补充消息的操作可能失败的情况,请在服务中自行实现对该操作执行的任何退避机制。设置构造订户时的最大ack扩展期限(java中的setMaxAckExtensionPeriod),以确保您的客户端将每条消息的ack截止期限延长足够长的时间来进行重试。