2017-02-03 63 views
0

問題:經過一段固定的重試次數後,我想將消息發送到一個錯誤隊列並從其原始隊列中消耗它。我想找到一個通用的解決方案,因爲我處理了很多不同的消息,並且根據他們引發的異常,我想採取不同的行動。我如何設置RecoveryCallback以便Spring在maxRetries之後觸發它?Spring RabbitTemplate setRetryTemplate&setRecoveryCallback ignored

我現在做什麼
我嘗試設置RetryTemplateRecoveryCallback。 當我運行應用程序並將消息發佈到test隊列時,我期望EListener#receive中的處理失敗3次,然後觸發配置的RecoveryCallback,然後將基於上下文的消息路由到特定的錯誤隊列。

實際發生的 實際上會發生什麼事是Spring啓動初始化與自己RabbitTemplateRabbitAdmin對象,因此不使用我的配置RabbitTemplate豆。

我有以下目錄結構:

rabbit 
    |___ EListener.java 
    |___ Rabbit.java 
test 
    |___ Test.java 

我在Rabbit.java

@Configuration 
public class Rabbit { 

    @Autowired 
    ConnectionFactory connectionFactory; 

    @Bean 
    public RabbitTemplate rabbitTemplate() { 
     RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); 
     rabbitTemplate.setRetryTemplate(createRetryTemplate()); 
     rabbitTemplate.setRecoveryCallback(createRecoveryCallback()); 
     return rabbitTemplate; 
    } 

    createRecoveryCallback() // Omitted for brevity 
    createRetryTemplate() // Omitted for brevity 
} 

EListener.java文件下面的代碼包含:

@Component 
public class EListener { 

    @Autowired 
    RabbitTemplate rabbitTemplate; 

    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "test", durable = "true"), exchange = @Exchange(value = "test", type = ExchangeTypes.TOPIC, durable = "true", autoDelete = "true"), key = "test")) 
    public void receive(Message m) throws Exception { 
     System.out.println(m); 
     throw new Exception(); 
    } 
} 

Test.java包含:

@SpringBootApplication 
@ComponentScan("rabbit") 
public class Test { 

    public static void main(String[] args) { 
     new SpringApplicationBuilder(Test.class).application().run(args); 
    } 
} 

回答

0

添加RetryTemplateRabbitTemplate是重試出版消息。

要在客戶端添加重試,您必須向偵聽器container's advice chain添加重試攔截器。

由於您使用的是@RabbitListener,建議鏈接在listener container factory @Bean上,這意味着您必須自己聲明一個,而不是依賴由boot創建的默認值。

無狀態重試執行內存中的重試;有狀態重試重發消息;它需要一個messageId屬性(或其他一些機制來唯一標識消息)。

+0

是否有可能僅僅替換當前用作默認恢復器的'RejectAndDontRequeueRecoverer'? – dparted

+0

不幸的不是;該恢復器硬連線到[引導的config'd重試攔截器](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework /boot/autoconfigure/amqp/SimpleRabbitListenerContainerFactoryConfigurer.java#L104)。你可以[連接你自己的bean](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconigure/amqp/RabbitAnnotationDrivenConfiguration.java#L62)使用boot的配置器,然後用自己的攔截器覆蓋'adviceChain'。 –

+0

然後我會這樣做。首先這樣做會很棒。謝謝您的幫助。 – dparted

相關問題