我正在寻找一种使用spring amqp和Rabbit MQ通过后退策略实现重试的好方法,但是要求是不应该阻止侦听器(因此可以自由处理其他消息)。我在此处看到了类似的问题,但其中不包含“退缩”的解决方案:
RabbitMQ和Spring amqp重试时不会阻止使用者
我的问题是:
如果上述假设是正确的,那么这是唯一的实现此方法的方法,即实现一个单独的重试队列(DLQ?),并为每条消息设置一个TTL(假设我们不想在退避间隔内阻塞线程)。
如果我们采用上述方法(DLQ或单独的队列),那么每次重试尝试是否都不需要单独的队列?如果仅使用1个队列进行重试,则同一队列将包含TTL范围从最小重试间隔到最大重试间隔的消息,并且如果队列前面的消息具有最大TTL,则后面的消息将不会即使它具有最小TTL也会拾取。这是根据此处的Rabbit MQ TTL文档(请参见警告):
还有另一种方法来实现无阻塞的重试机制吗?
添加一些配置信息以帮助对@garyrussel进行故障排除:
队列配置:
<rabbit:queue name="regular_requests_queue"/>
<rabbit:queue name="retry_requests_queue">
<rabbit:queue-arguments>
<entry key="x-dead-letter-exchange" value="regular_exchange" />
</rabbit:queue-arguments>
</rabbit:queue>
<rabbit:direct-exchange name="regular_exchange">
<rabbit:bindings>
<rabbit:binding queue="regular_requests_queue" key="regular-request-key"/>
</rabbit:bindings>
</rabbit:direct-exchange>
<rabbit:direct-exchange name="retry_exchange">
<rabbit:bindings>
<rabbit:binding queue="retry_requests_queue"/>
</rabbit:bindings>
</rabbit:direct-exchange>
<bean id="retryRecoverer" class="com.testretry.RetryRecoverer">
<constructor-arg ref="retryTemplate"/>
<constructor-arg value="retry_exchange"/>
</bean>
<rabbit:template id="templateWithOneRetry" connection-factory="connectionFactory" exchange="regular_exchange" retry-template="retryTemplate"/>
<rabbit:template id="retryTemplate" connection-factory="connectionFactory" exchange="retry_exchange"/>
<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="1"/>
</bean>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)