RabbitMQ 詳解(三)------消息過期、死信隊列和服務端流控

一.TTL (消息的過期時間)

1.兩種設置方式:

(1)通過隊列屬性設置消息過期時間

      所有隊列中的消息超過時間未被消費時,都會過期。

@Bean("ttlQueue")
public Queue queue() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("x-message-ttl", 11000); // 隊列中的消息未被消費 11 秒後過期
return new Queue("GP_TTL_QUEUE", true, false, false, map);
}

  (2)設置單條消息的過期時間

​
@Bean("ttlQueue")
public Queue queue() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("x-message-ttl", 11000); // 隊列中的消息未被消費 11 秒後過期
return new Queue("GP_TTL_QUEUE", true, false, false, map);
}

​

      如果同時指定了 Message TTL 和 Queue TTL,則小的那個時間生效。

二.死信隊列

 1.什麼情況下消息會變成死信?
   1)消息被消費者拒絕並且未設置重回隊列:(NACK || Reject ) && requeue== false
   2)消息過期
   3)隊列達到最大長度,超過了最大消息數或字節數,最先入隊的消息會被髮送到死信交換機。

2.死信隊列如何使用?

   1)聲 明 死 信 交 換 機  、死 信 隊 列,相互綁定



//死信交換機
@Bean("deatLetterExchange")
public TopicExchange deadLetterExchange() {
return new TopicExchange("GP_DEAD_LETTER_EXCHANGE", true, false, new HashMap<>());
}
​@Bean("deatLetterQueue")
public Queue deadLetterQueue() {
return new Queue("GP_DEAD_LETTER_QUEUE", true, false, false, new HashMap<>());
}
@Bean
public Binding bindingDead(@Qualifier("deatLetterQueue") Queue queue,@Qualifier("deatLetterExchange")
TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("#"); // 無條件路由
}

 2)聲明原交換機、原隊列,相互綁定。隊列中的過期消息,因爲沒有消費者,會變成死信。指定原隊列的死信交換機

//原交換機
@Bean("oriUseExchange")
public DirectExchange exchange() {
return new DirectExchange("GP_ORI_USE_EXCHANGE", true, false, new HashMap<>());
}

@Bean("oriUseQueue")
public Queue queue() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("x-message-ttl", 10000); // 10 秒鐘後成爲死信
map.put("x-dead-letter-exchange", "GP_DEAD_LETTER_EXCHANGE"); // 隊列中的消息變成死信後,進入死信

return new Queue("GP_ORI_USE_QUEUE", true, false, false, map);
}

//綁定​
@Bean
public Binding binding(@Qualifier("oriUseQueue") Queue queue,@Qualifier("oriUseExchange") DirectExchange
exchange) {
return BindingBuilder.bind(queue).to(exchange).with("test.ori.use");
}

 3)最終消費者監聽死信隊列。
 4)生產者發送消息。

         

三.服務端流控

        隊列有兩個控制長度的屬性:x-max-length:隊列中最大存儲最大消息數,超過這個數量,隊頭的消息會被丟棄。x-max-length-bytes:隊列中存儲的最大消息容量,超過這個容量,隊頭的消息會被丟棄。通過設置隊列長度在消息堆積的情況下會刪除先入隊的消息。但如何在消息的產生速度遠大於消費速度的情況下實現服務限流呢。

         1.內存控制

       RabbitMQ 會在啓動時檢測機器的物理內存數值。默認當 MQ 佔用 40% 以上內存時,MQ 會主動拋出一個內存警告並阻塞所有連接。可以通過修改rabbitmq.config 文件來調整內存閾值,默認值是 0.4,如下所示: ​{vm_memory_high_watermark, 0.4}。如果設置成0,則所有消息都不能發佈。

          2.磁盤控制

         通過磁盤來控制消息的發佈。當磁盤空間低於指定的值時(默認50MB),觸發流控措施。

         disk_free_limit.relative = 3.0
         disk_free_limit.absolute = 2GB

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章