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

一、过期时间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发送到死信队列

四、延迟队列

在这里插入图片描述

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一梦无痕bzy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值