mq设置过期时间、优先级、死信队列、延迟队列

梦想不抛弃苦心追求的人,只要不停止追求,你们会沐浴在梦想的光辉之中。再美好的梦想与目标,再完美的计划和方案,如果不能尽快在行动中落实,最终只能是纸上谈兵,空想一番。只要瞄准了大方向,坚持不懈地做下去,才能够扫除挡在梦想前面的障碍,实现美好的人生蓝图。mq设置过期时间、优先级、死信队列、延迟队列,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、过期时间TTL:

对消息或者队列设置过期时间,则时间到了相应的消息或者队列里的全部消息都被删除并放到死信队列里,消费者无法消费。如果对消息和该消息所在队列都设置了过期时间,则以过期时间短的为准(以先过期的为准)

1、给队列设置消息过期时间:

声明队列时需要设置x-message-ttl属性,并设置过期时间,推送到该队列中的所有消息,在时间到后都会被删除并放到死信队列中

/**
 * 声明过期队列
 * @return
 */
@Bean
public Queue test2Queue() {
    Map<String, Object> map = new HashMap<>();
    map.put("x-message-ttl", 5000); // 队列中的每一个消息未被消费则5秒后过期,被自动删除并移到死信队列
    return new Queue("test2_Queue",true,false,false,map);
}

在这里插入图片描述
如果队列是过期队列会有TTL标识

2、指定某条消息的过期时间:

生产者代码:

@GetMapping("/sendMessage")
public void sendMessage() {

    MessageProperties messageProperties = new MessageProperties();
    //设置过期时间
    messageProperties.setExpiration("10000");

    //这个参数是用来做消息的唯一标识
    //发布消息时使用,存储在消息的headers中
    CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());


    Message message = new Message("lalalalla".getBytes(StandardCharsets.UTF_8), messageProperties);

    rabbitTemplate.convertAndSend("direct_Exchange", "test1_Queue", message, correlationData);
}

消费者代码:

package com.example.demo.mq;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class Test1QueueReceiver {


    @RabbitListener(queues = "test1_Queue")
    public void process(String mes, Channel channel, Message message) {
        System.err.println(mes);
        //消息的所有相关信息都可以在message中找到
        System.err.println(message.toString());
    }
}

注意:
RabbitMQ只会淘汰队列头部的过期消息。如果单独给一条消息设置ttl,先入队列的消息过期时间如果设置比较长,后入队列的设置时间比较短,那么消息就不会及时的被淘汰,会导致消息的堆积问题。

二、优先级

设置优先级的目的是可以让队列中的消息按照设置好的优先级由大到小排序,然后优先级高的先消费

1、队列需要设置为优先级队列

/**
 * 声明优先级队列
 * @return
 */
@Bean
public Queue test4Queue() {
    Map<String, Object> map = new HashMap<>();
    //设置优先级,范围0-255,此处设为10,则本队列允许优先级的范围为0-10。优先级设置的越高,对服务器的压力越大
    map.put("x-max-priority", 10);
    return new Queue("test4_Queue",true,false,false,map);
}

在这里插入图片描述
如果队列有优先级会有Pri标识

2、消息需要加优先级属性

@GetMapping("/sendMessage")
public void sendMessage() {

    for (Integer i = 1; i < 11; i++) {
        MessageProperties messageProperties = new MessageProperties();
        //设置优先级
        messageProperties.setPriority(i);

        //这个参数是用来做消息的唯一标识
        //发布消息时使用,存储在消息的headers中
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());


        Message message = new Message(i.toString().getBytes(StandardCharsets.UTF_8), messageProperties);

        rabbitTemplate.convertAndSend("direct_Exchange", "test4_Queue", message, correlationData);
    }


}

3、消费者代码

当消息队列中的代码积压一会后,执行下面的代码,则会发现消息从优先级大的开始消费

package com.example.demo.mq;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class Test4QueueReceiver {


    @RabbitListener(queues = "test4_Queue")
    public void process(String mes, Channel channel, Message message) {
        System.err.println(mes);

        //消息的所有相关信息都可以在message中找到
        System.err.println(message.toString());
    }
}

注意:
只有当消费者消费能力不足,即消息无法被及时消费而阻塞的时候,优先队列才会根据优先级来分配任务的执行顺序。否则还是先到先消费

三、死信队列

1、概念

在这里插入图片描述

2、工作流程

在这里插入图片描述

3、springboot代码

3.1、定义交换机和队列

/**
 * 声明死信交换机
 * @return DirectExchange
 */
@Bean
public DirectExchange dlxExchange() {
    return new DirectExchange("dlxExchange", true, false);
}

/**
 * 声明死信队列
 * @return Queue
 */
@Bean
public Queue dlxQueue() {
    return new Queue("dlxQueue",true,false,false);
}

/**
 * 绑定死信队列到死信交换机
 * @return Binding
 */
@Bean
public Binding binding() {
    return BindingBuilder.bind(dlxQueue()).to(dlxExchange()).with(dlxQueue().getName());
}



/**
 * 声明定长队列,并定义对应的死信交换机
 * @return
 */
@Bean
public Queue test5Queue() {
    Map<String, Object> map = new HashMap<>();
    // 队列中的消息最多只能有两个,如果超过,则先放入队列的消息会被删除投递到死信交换机。
    map.put("x-max-length", 2);
    //死信交换机的名称
    map.put("x-dead-letter-exchange",dlxExchange().getName());
    //死信交换机和死信队列绑定的routingKey
    map.put("x-dead-letter-routing-key",dlxQueue().getName());
    return new Queue("test5_Queue",true,false,false,map);
}


/**
 * 交换机与队列绑定
 * @return
 */
@Bean
Binding test5Binding(){
    return BindingBuilder.bind(test5Queue()).to(directExchange()).with(test5Queue().getName());
}

在这里插入图片描述
队列设置成定长队列会有Lim标识
队列绑定了死信队列会有DLX、DLK标识

3.2、生产者代码

@GetMapping("/sendMes")
public void sendMes() {
    rabbitTemplate.convertAndSend("direct_Exchange", "test5_Queue", "hehehhe");
}

当队列中的消息个数超过两个时,先放入队列的消息会被删除投递到死信交换机,死信交换机会根据routingKey发送到死信队列

四、延迟队列

在这里插入图片描述

也就是间接的实现延迟队列,最后消费者监听的是死信队列

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/153426.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!