RabbitMQ实现延时消息的两种方法
1、死信队列
1.1消息什么时候变为死信(dead-letter)
- 消息被否定接收,消费者使用basic.reject 或者 basic.nack并且requeue 重回队列属性设为false。
- 消息在队列里得时间超过了该消息设置的过期时间(TTL)。
- 消息队列到达了它的最大长度,之后再收到的消息。
1.2死信队列的原理
当一个消息再队列里变为死信时,它会被重新publish到另一个exchange交换机上,这个exchange就为DLX。因此我们只需要在声明正常的业务队列时添加一个可选的"x-dead-letter-exchange"参数,值为死信交换机,死信就会被rabbitmq重新publish到配置的这个交换机上,我们接着监听这个交换机就可以了。
1.3 代码实现
- 引入amqp依赖
- 声明交换机,队列
package com.lank.demo.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class RabbitmqConfig {
//死信交换机,队列,路由相关配置
public static final String DLK_EXCHANGE = "dlk.exchange";
public static final String DLK_ROUTEKEY = "dlk.routeKey";
public static final String DLK_QUEUE = "dlk.queue";
//业务交换机,队列,路由相关配置
public static final String DEMO_EXCHANGE = "demo.exchange";
public static final String DEMO_QUEUE = "demo.queue";
public static final String DEMO_ROUTEKEY = "demo.routeKey";
//延时插件DelayedMessagePlugin的交换机,队列,路由相关配置
public static final String DMP_EXCHANGE = "dmp.exchange";
public static final String DMP_ROUTEKEY = "dmp.routeKey";
public static final String DMP_QUEUE = "dmp.queue";
@Bean
public DirectExchange demoExchange(){
return new DirectExchange(DEMO_EXCHANGE,true,false);
}
@Bean
public Queue demoQueue(){
//只需要在声明业务队列时添加x-dead-letter-exchange,值为死信交换机
Map<String,Object> map = new HashMap<>(1);
map.put("x-dead-letter-exchange",DLK_EXCHANGE);
//该参数x-dead-letter-routing-key可以修改该死信的路由key,不设置则使用原消息的路由key
map.put("x-dead-letter-routing-key",DLK_ROUTEKEY);
return new Queue(DEMO_QUEUE,true,false,false,map);
}
@Bean
public Binding <