使用spring amqp和rabbitmq实现带回退的非阻塞重试

使用spring amqp和rabbitmq实现带回退的非阻塞重试,rabbitmq,spring-amqp,spring-retry,Rabbitmq,Spring Amqp,Spring Retry,我正在寻找一种使用spring amqp和Rabbit MQ的退避策略实现重试的好方法,但要求不阻止侦听器(因此可以自由处理其他消息)。我看到这里提出/回答了一个类似的问题,但不包括“后退”的解决方案: 我的问题是: 默认的spring retry实现是否在重试时阻止线程?这表明确实如此 如果上述假设成立,那么实现单独的重试队列(DLQ?)并为每条消息设置一个TTL(假设我们不想在回退间隔内阻塞线程)是唯一的方法 如果我们采用上述方法(DLQ或单独的队列),那么每次重试不需要单独的队列吗?

我正在寻找一种使用spring amqp和Rabbit MQ的退避策略实现重试的好方法,但要求不阻止侦听器(因此可以自由处理其他消息)。我看到这里提出/回答了一个类似的问题,但不包括“后退”的解决方案:

我的问题是:

  • 默认的spring retry实现是否在重试时阻止线程?这表明确实如此

  • 如果上述假设成立,那么实现单独的重试队列(DLQ?)并为每条消息设置一个TTL(假设我们不想在回退间隔内阻塞线程)是唯一的方法

  • 如果我们采用上述方法(DLQ或单独的队列),那么每次重试不需要单独的队列吗?如果我们仅使用1个队列进行重试,则同一队列将包含TTL范围从最小重试间隔到最大重试间隔的消息,并且如果队列前面的消息具有最大TTL,则即使其具有最小TTL,也不会拾取其后面的消息。这符合Rabbit MQ TTL文档的要求(请参阅注意事项):

  • 是否有其他方法实现非阻塞回退重试机制

  • 添加一些配置信息以帮助对@garyrussel进行故障排除:

    队列配置:

    
    
  • 通过4
  • 您可以将retry max attempts=1与子类
    RepublishMessageRecoverer
    一起使用,并实现
    additionalHeaders
    来添加重试计数头

    然后,每次尝试都可以重新发布到不同的队列

    恢复程序的结构并不适合发布到不同的队列(我们应该对此进行更改),因此您可能需要编写自己的恢复程序,并将其委托给几个
    RepubishMessageRecoverer
    中的一个


    考虑一下您的框架解决方案。

    这是我最终实现的最终解决方案。每个“重试间隔”有1个队列,每个重试队列有1个exchange。它们都被传递给定制的RepublichRecover,后者创建一个恢复程序列表

    消息中添加了一个名为“RetryCount”的自定义头,根据“RetryCount”的值,消息将以不同的“过期时间”发布到右侧的exchange/队列。每个重试队列都使用一个DLX进行设置,该DLX设置为“常规交换”(即请求进入常规队列)

    
    
    以下是CustomRetryRecoverer的代码:

    公共类CustomRetryRecoverer扩展
    重新发布消息恢复程序{
    私有静态最终字符串RETRY\u COUNT\u HEADER\u NAME=“RetryCount”;
    private List retryExecutors=new ArrayList();
    私有触发器retryTemplate retryTemplate;
    公共触发器RetryRecoverer(AmqpTemplate[]retryTemplates,String[]exchangeNames,TriggersRetryTemplate retryTemplate){
    超级(retryTemplates[0],exchangeNames[0]);
    this.retryTemplate=retryTemplate;
    //获取两个数组大小中较低的一个
    int executorCount=(exchangeNames.length

    “CustomRetryTemplate”的代码未在此处发布,但它包含maxRetryCount、initialInterval和乘数的简单变量。

    您是否查看了rabbitmq delayer插件,该插件在exchange而不是队列中延迟消息?根据文档,发送到delayer exchange的消息似乎在exchange级别是持久的

    使用自定义重试计数消息头和延迟器交换,我们可以实现非阻塞行为,而不需要这些中间队列dlx和tem的丑陋