RabbitMq高階特性之死信佇列 通俗易懂 超詳細 【內含案例】
阿新 • • 發佈:2020-07-25
RabbitMq高階特性之死信佇列 又稱 死信交換機 DLX
當訊息成為 Dead message 後,會重新發送到另一個交換機,這個交換機就是 DLX
訊息成為死信的情況公有三種:
- 佇列訊息長度達到限制
- 消費者拒接消費訊息 basicNack/basicReject,並且不把訊息重新放回原目標佇列,requeue=false;
- 原佇列訊息存在訊息過期設定,訊息達到過期時間
前提
一、更改RabbitMqConfig.java檔案
import org.springframework.amqp.core.*; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * RabbitMq 配置類 */ @Configuration public class RabbitMqConfig { private static final String TOPIC_EXCHANGE_NAME = "topic_exchange"; private static final String TOPIC_QUEUE_NAME = "topic_queue"; public static final String DLX_EXCHANGE = "dlx_exchange"; public static final String DLX_QUEUE = "dlx_queue"; public static final String DLX_ROUTING_KEY = "dlx"; /** * 建立 交換機 * @return */ @Bean public Exchange itemTopicExchange(){ return ExchangeBuilder.topicExchange(TOPIC_EXCHANGE_NAME).build(); } @Bean public Exchange DlxExchange(){ return ExchangeBuilder.directExchange(DLX_EXCHANGE).build(); } /** * 建立 佇列 * @return */ @Bean public Queue itemQueue(){ //QueueBuilder.durable(TOPIC_QUEUE_NAME).withArgument("x-message-ttl",3000).build(); //與下句程式碼 效果一致 寫一個就可以 //與死信交換機繫結 return QueueBuilder.durable(TOPIC_QUEUE_NAME).ttl(3000).deadLetterExchange(DLX_EXCHANGE).deadLetterRoutingKey(DLX_ROUTING_KEY).build(); } @Bean public Queue dlxQueue(){ return QueueBuilder.durable(DLX_QUEUE).build(); } /** * 繫結 交換機與佇列 * @param exchange * @param queue * @return */ @Bean public Binding itemQueueExchange(@Qualifier("itemTopicExchange") Exchange exchange, @Qualifier("itemQueue") Queue queue){ return BindingBuilder.bind(queue).to(exchange).with("item.#").noargs(); } @Bean public Binding itemQueueExchange(@Qualifier("dlxExchange") Exchange exchange, @Qualifier("dlxQueue") Queue queue){ return BindingBuilder.bind(queue).to(exchange).with(DLX_ROUTING_KEY).noargs(); } }
二、測試
- 如有topic_queue已存在,請刪除
- 執行ProducerTest.java單元測試
- 過期的死信佇列會跑到DLX_QUEUE佇列中
三、小結
- 死信佇列也可以建立一個消費者來訊息死信訊息
- 可以在RabbitMqConfig.java檔案中的itemQueue()方法中設定佇列的最大限度,QueueBuilder.maxLendth(5); 當出入大於5個訊息,多餘的會丟到死信佇列中
- channel.basicNack(deliveryTag, true, false);確認訊息但是不傳送回原目標佇列,會丟到死信佇列中