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

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