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

本文介绍了如何在Spring Boot中使用RabbitMQ实现消息的过期机制、设置消息优先级以及创建死信队列,包括队列设置、消息生产和消费的示例,以及如何通过定时监听死信队列实现延迟队列功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

四、延迟队列

在这里插入图片描述

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

<think>好的,我现在需要准备关于RabbitMQ的面试题。首先,我应该回忆一下RabbitMQ的基本概念,比如它是什么,有什么作用。然后,常见的面试问题可能包括它的核心组件,比如生产者、消费者、交换机、队列、绑定等。 接下来,可能需要了解RabbitMQ的消息确认机制,比如ack和nack,以及持久化相关的设置。还有关于交换机的类型,比如直连、主题、扇出、头交换机,每种类型的使用场景。 然后,问题可能涉及如何确保消息不丢失,如何处理消息重复消费,死信队列的作用,以及如何实现延迟队列。还有集群和高可用性的配置,比如镜像队列。 我还需要思考一下实际应用中的问题,比如如何保证消息顺序,如何监控和管理RabbitMQ,性能调优的注意事项。可能还会问到和其他消息队列比如Kafka的区别,优缺点比较。 另外,一些高级特性如插件机制,消息的TTL,优先级队列,RPC模式的使用也可能被提及。需要复习一下AMQP协议的基本模型,以及RabbitMQ在其中的角色。 可能还要准备一些场景题,比如设计一个消息队列系统时如何选择交换机类型,如何处理消费者宕机的情况,如何实现负载均衡等。同时,故障排查的常见方法,比如日志查看,管理界面的使用,网络问题的诊断。 最后,要确保理解RabbitMQ的核心优势,比如可靠性、灵活的路由、集群管理,以及它的适用场景,比如解耦系统、异步处理、流量削峰等。需要结合实际案例说明如何应用这些特性解决问题。</think>以下整理了常见的RabbitMQ面试题及核心知识点,使用$$...$$格式展示关键概念: --- ### 一、基础概念 1. **RabbitMQ是什么?** $$ \text{基于AMQP协议的开源消息代理,用于实现系统间的异步通信和解耦} $$ 2. **核心组件** - 生产者(Producer) - 消费者(Consumer) - 交换机(Exchange) $$ \text{类型:直连(Direct)、主题(Topic)、扇出(Fanout)、头(Headers)} $$ - 队列(Queue) - 绑定(Binding) --- ### 二、核心机制 3. **消息确认(ACK)** $$ \text{消费者手动ack确保消息可靠传递,nack可触发重试或进入死信队列} $$ 4. **持久化** $$ \text{队列(durable=true)+ 消息(delivery_mode=2)+ 交换机持久化} $$ 5. **死信队列(DLX)** $$ \text{消息被拒绝、TTL过期或队列满时,自动转发到死信交换机} $$ --- ### 三、高级特性 6. **延迟队列实现** $$ \text{方案1:消息TTL + 死信队列;方案2:rabbitmq-delayed-message-exchange插件} $$ 7. **集群与高可用** - 镜像队列(Mirrored Queues) $$ \text{ha-mode=all/exactly/nodes,实现队列多节点复制} $$ 8. **消息重复消费** $$ \text{解决方案:幂等性设计(唯一ID+状态校验)} $$ --- ### 四、场景问题 9. **如何保证消息不丢失?** ```plaintext 1. 生产者开启confirm模式 2. 队列/消息持久化 3. 消费者手动ACK ``` 10. **RabbitMQ vs Kafka** $$ \text{RabbitMQ:强一致性、复杂路由;Kafka:高吞吐、顺序读写、日志场景} $$ --- ### 五、故障排查 11. **消息堆积怎么办?** - 增加消费者 - 设置队列最大长度(x-max-length) - 启用惰性队列(x-queue-mode=lazy) --- ### 六、实战示例 12. **发送消息代码片段(Python)** ```python channel.basic_publish( exchange='orders', routing_key='payment', body=message, properties=pika.BasicProperties(delivery_mode=2) # 持久化 ) ``` --- **附:高频考点思维导图** ``` 可靠性 ➜ ACK机制 + 持久化 路由逻辑 ➜ 交换机类型选择 高可用 ➜ 镜像队列 + 集群 疑难场景 ➜ 死信队列 + 延迟消息 + 幂等性 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一梦无痕bzy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值