@[toc]RabbitMQ中的消息长时间不消费会不会过期?用过RabbitMQ的朋友可能会有这样的疑问。今天宋弟兄就来和大家讨论一下这个问题。1.违约情况首先,我们来看一下违约情况。默认情况下,消息是不会过期的,也就是我们在工作日发送消息的时候,如果不设置任何消息过期相关的参数,那么消息是不会过期的,即使消息没有被消费,也会一直被存储在队列中。在这种情况下,我不需要演示具体的代码。宋哥之前的文章说到RabbitMQ基本都是这样的。2、TTLTTL(Time-To-Live),消息存活的时间,即消息的有效期。如果我们希望消息有生存时间,那么我们可以通过设置TTL来实现这个需求。如果消息的存活时间超过了TTL还没有被消息发送出去,此时消息就会变成死信。关于死信和死信队列,后面宋哥给大家介绍一下。TTL的设置有两种不同的方式:在声明队列的时候,我们可以在队列属性中设置消息的有效期,这样所有进入队列的消息都会有相同的有效期。发送消息时设置消息的有效期,使不同的消息有不同的有效期。如果两个都设置了呢?以最短时间为准。当我们设置消息的有效期时,消息过期就会从队列中删除(进入死信队列,下同,不再标注),但是相应的删除时机有些区别对两种方法:对于第一种方式,当消息队列设置过期时间时,消息过期会被删除,因为消息进入RabbitMQ后,存在于一个消息队列中,而队列的头部是最早过期的消息,所以RabbitMQ只需要一个定时器任务从头部开始扫描过期消息,有则删除。对于第二种方法,当消息过期时,不会立即删除,而是在消息传递给消费者时删除,因为在第二种方法中,每条消息的过期时间是不同的。要知道哪条消息过期了,必须遍历队列中的所有消息。当有很多消息时,这会消耗更多的性能。因此,对于第二种方法,在消息要投递给消费者时删除消息。介绍完TTL,我们再来看看具体的用法。接下来所有的代码松哥都会以SpringBoot封装的AMPQ为例进行讲解。2.1单条消息的过期我们先来看看单条消息的过期时间。首先创建一个SpringBoot工程,引入Web和RabbitMQ依赖,如下:然后在application.properties中配置RabbitMQ的连接信息,如下:spring.rabbitmq.host=127.0.0.1spring.rabbitmq.port=5672spring.rabbitmq。username=guestspring.rabbitmq.password=guestspring.rabbitmq.virtual-host=/接下来稍微配置消息队列:@ConfigurationpublicclassQueueConfig{publicstaticfinalStringJAVABOY_QUEUE_DEMO="javaboy_queue_demo";publicstaticfinalStringJAVABOY_EXCHANGE_DEMO="ange_pubic_ex"staticfinalStringHELLO_ROUTING_KEY="hello_routing_key";@BeanQueuequeue(){returnnewQueue(JAVABOY_QUEUE_DEMO,true,false,false);}@BeanDirectExchangedirectExchange(){returnnewDirectExchange(JAVABOY_EXCHANGE_DEMO,true,false);}Bean绑定binding(){returnBindingBuilder.bind(queue()).to(directExchange()).with(HELLO_ROUTING_KEY);}}这个配置类主要做了三件事:配置消息队列,配置交换机,将两者绑定在一起。首先配置一个消息队列,新建一个Queue:第一个参数是消息队列的名称;第二个参数表示消息是否持久化;第三个参数表示消息队列是否独占,一般我们设置为false,即不独占;第四个参数表示如果队列没有任何订阅的消费者,则自动删除该队列,一般适用于临时队列。配置DirectExchange交换机。将交换器和队列绑定在一起。这个配置应该很简单,没什么好解释的,有个独占性,松哥这里多说两句:关于独占性,如果设置为true,消息队列只能被创建的Connection访问它,其他的Connection都是无法访问消息队列的。如果尝试在不同的连接中重新声明或访问独占队列,系统会报资源锁定错误。另一方面,对于独占队列,当连接断开时,消息队列也会被自动删除(不管队列是否声明为持久队列)。接下来提供消息发送接口,如下:@RestControllerpublicclassHelloController{@AutowiredRabbitTemplaterabbitTemplate;@GetMapping("/hello")publicvoidhello(){Messagemessage=MessageBuilder.withBody("hellojavaboy".getBytes()).setExpiration("10000").build();rabbitTemplate.convertAndSend(QueueConfig.JAVABOY_QUEUE_DEMO,消息);}}在创建Message对象的时候,我们可以设置消息的过期时间,这里我们设置消息的过期时间为10秒。就是这样!接下来我们启动项目,进行消息发送测试。消息发送成功后,由于没有消费者,消息不会被消费。打开RabbitMQ管理页面,点击Queues选项卡,10s后,我们会发现消息消失了:很简单!设置单条消息的过期时间就是在发送消息时设置消息的有效期。2.2队列消息过期设置队列的消息过期时间如下:@BeanQueuequeue(){Map
