我可以使用DLQ配置Spring Cloud Stream with RabbitMQ的最大尝试次数吗

xqkwcwgp  于 2022-11-08  发布在  RabbitMQ
关注(0)|答案(1)|浏览(215)

我正在使用Spring Cloud Stream和Rabbit,我使用这里定义的配置来设置一个死信队列(DLQ),它运行得非常好。
我想做的是设置消息在被丢弃之前进入DLQ的最大次数-是否可以通过config设置?如果可以,如何设置?如果不能,我应该做什么来实现此行为?
我正在寻找最佳答案的代码示例,最好是在Kotlin(如果相关)

mhd8tkvw

mhd8tkvw1#

这取决于你是否使用了仲裁队列。我不相信没有仲裁队列的情况下会有默认的配置。但是,你应该能够在自定义的报头或消息本身中存储重新传递计数。
然后,如果您在应用程序中设置了一个MAX_REDELIVERY_COUNT常量,则可以检查消息是否超过了最大重新传递次数。
如果您没有使用仲裁队列,我会看一下这个答案:How do I set a number of retry attempts in RabbitMQ?。这个答案有很多不错的选项。
但是,当使用仲裁队列时,您可以设置delivery-limit选项。有关该选项的更多信息,可以在此处找到:https://www.rabbitmq.com/quorum-queues.html#feature-matrix。

编辑1:使用自定义标题

要发布带有自定义标题的邮件,请执行以下操作:

Map<String, Object> headers = new HashMap<String, Object>();
headers.put("latitude",  51.5252949);
headers.put("longitude", -0.0905493);

channel.basicPublish(exchangeName, routingKey,
             new AMQP.BasicProperties.Builder()
               .headers(headers)
               .build(),
               messageBodyBytes);

如www.example.com上所示https://www.rabbitmq.com/api-guide.html#publishing。
问题是标头不能简单地更新。但是,您可以通过一种变通方法来实现这一点。假设您希望每个消息最多重试5次。如果无法处理该消息,则将其发送到DLX。如果该消息未超过最大重试次数,则读取该消息的原始标头,更新自定义重试计数标头,然后将其重新发送到原始队列。
如果消息进入DLX并且确实超过了最大重试计数,则使用不同的路由关键字将消息按原样发送到DLX,该路由关键字绑定到“最终”停用消息的队列。
这就意味着你会在一个简化的图表中得到这样的东西:

这只是一个想法,我不知道它是否一定会工作,但这是最好的,我能想到在你的情况。

编辑2:使用autoBindDlq

看起来Spring Cloud Stream Binder for RabbitMQ有这个选项。在https://github.com/spring-cloud/spring-cloud-stream-binder-rabbit上找到的文档中,它说:
通过使用可选的autoBindDlq选项,您可以配置绑定器以创建和配置死信队列(DLQ)(和死信交换DLX,以及路由基础结构)。默认情况下,死信队列的名称为目的地名称,后面附加.dlq。如果启用重试(maxAttempts > 1),失败的消息将在重试次数耗尽后传递到DLQ。如果禁用重试(maxAttempts = 1),则应将requeueRejected设置为false(默认值),以便将失败的消息路由到DLQ,而不是重新排队。此外,republishToDlq导致绑定器向DLQ发布失败消息(而不是拒绝它)。此功能允许附加信息(例如x-exception-stacktrace信头中的堆栈追踪)加入至信头中的消息。如需截断堆栈追踪的详细信息,请参阅frameMaxHeadroom属性。此选项不需要启用重试。您可以在尝试一次后重新发布失败的消息。从1.2版开始,您可以配置重新发布消息的传递模式。请参阅republishDeliveryMode属性。

相关问题