Spring 在最大尝试次数后,在队列尾部重新排队兔子AMQP消息

Spring 在最大尝试次数后,在队列尾部重新排队兔子AMQP消息,spring,rabbitmq,amqp,spring-amqp,spring-rabbit,Spring,Rabbitmq,Amqp,Spring Amqp,Spring Rabbit,我目前正在使用RabbitMQ和spring(spring-rabbit-1.2.0-RELEASE),配置如下: <rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/> <!-- Asynchronous exchanges --> <!-- Admin --> <rabbit:admin connection-factory="connectionFact

我目前正在使用RabbitMQ和spring(spring-rabbit-1.2.0-RELEASE),配置如下:

<rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/>
<!-- Asynchronous exchanges -->
<!-- Admin -->
<rabbit:admin connection-factory="connectionFactory"/>

<!-- Error Handler -->
<bean id="biErrorHandler" class="my.project.sync.BiErrorHandler" />
<!-- Message converter -->
<bean id="biMessageConverter" class="my.project.sync.BiMessageConverter"/>

<bean id="retryInterceptor" class="org.springframework.amqp.rabbit.config.StatefulRetryOperationsInterceptorFactoryBean">
    <property name="messageRecoverer" ref="rejectAndDontRequeueRecoverer"/>
    <property name="retryOperations" ref="retryTemplate" />
    <property name="messageKeyGenerator" ref="biKeyGenerator" />
</bean> 

<bean id="biKeyGenerator" class="my.project.sync.BiMessageKeyGenerator"/>
<bean id="rejectAndDontRequeueRecoverer" class="org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer"/>

<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
    <property name="backOffPolicy">
        <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
            <property name="initialInterval" value="3000" />
            <property name="maxInterval" value="30000" />
        </bean>     
    </property>
    <property name="retryPolicy">
        <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
            <property name="maxAttempts" value="3" />
        </bean>     
    </property>
</bean>  

 <rabbit:queue id="biSynchronizationQueue" name="BI_SYNCHRONIZATION_QUEUE" durable="true" />
<rabbit:listener-container message-converter="biMessageConverter" concurrency="1" 
    connection-factory="connectionFactory"
    error-handler="biErrorHandler"
    advice-chain="retryInterceptor"
    acknowledge="auto">
    <rabbit:listener queues="BI_SYNCHRONIZATION_QUEUE" ref="biSynchronizationService" method="handleMessage"/>
</rabbit:listener-container>

我想在第三次尝试后在队列尾部重新查询消息。但我找不到一个方法来实现这一点

有人有主意吗


提前感谢您的帮助。

请使用自定义的
消息恢复程序
,使用
rabbitmplate
将消息发送到队列后面,而不是使用
拒绝和拒绝队列恢复程序
;然后抛出一个
AmqpRejectAndDontRequeueException
,这样消息将被拒绝


您可以将
拒绝和dontrequeuerecover子类化,在
recover()
中发送消息,然后调用
super.recover()
(这只会引发异常)。或者只需在您自己的
recover()
中执行所有的实现,我使用了这个技巧,但使用死信队列的方向略有不同。对我来说,这比将消息放在队列的末尾更加明确

 <rabbit:queue name="content.variantchange.queue" durable="true" queue-arguments="queueArguments"/>

<util:map id="queueArguments">
    <entry key="x-dead-letter-exchange" value="content.deadletter.topic"/>
</util:map>

  <rabbit:fanout-exchange name="content.deadletter.topic">
    <rabbit:bindings>
        <rabbit:binding queue="content.deadletter.queue"/>
    </rabbit:bindings>
</rabbit:fanout-exchange>

<rabbit:queue name="content.deadletter.queue" durable="true"/>

一旦你有了死信队列,你可以通过另一个消费者做任何你想做的事情(包括将它添加回原始队列)

我还使用了Gary推荐的侦听器的无状态版本,这使我不必担心消息id生成器

<bean id="retryInterceptor" class="org.springframework.amqp.rabbit.config.StatelessRetryOperationsInterceptorFactoryBean">
    <property name="messageRecoverer" ref="rejectAndDontRequeueRecoverer"/>
    <property name="retryOperations" ref="retryTemplate" />
</bean>


谢谢Gary,我明天会试试,然后回来汇报!仅供参考,我们在即将发布的1.3版本中添加了一个
RepubishMessageRecoverer;请参阅此处最后一段:@GaryRussell您认为RepublishMessageRecoverer相对于使用死信交换的主要好处是什么?其实差别不大,只是一种替代方法。然而,有几件事:1。重新发布的消息获取
x-exception-stacktrace
x-exception-message
标题。2.您可以根据消息内容路由到不同的交换/路由密钥(尽管这需要一些自定义编码-将
rabbitmplate子类化
,并覆盖
发送(交换、密钥、消息)
)。3.您可以进一步修改消息(使用相同的技术)。4.使用
DLE
转发消息时,消息头中包含一些特定于兔子的信息,但没有与失败相关的应用程序级信息。很好的示例。。。但我如何使用注释和最新版本来设置它,因为恢复程序应该是
MethodInvocationRecoverer
?我发现@GaryRussell一年前编写的这个旧定义不再有效:(
.recover(new RejectAndDontRequeueRecoverer())