代码地址: 码云
队列中的消息可能会变成死信消息(dead-lettered),进而当以下几个事件任意一个发生时,消息将会被重新发送到一个交换机:
-
1、消息被消费者使用basic.reject或basic.nack方法并且requeue参数值设置为false的方式进行消息确认(negatively acknowledged)
-
2、消息由于消息有效期(per-message TTL)过期
-
3、消息由于队列超过其长度限制而被丢弃
注意,队列的有效期并不会导致其中的消息过期
核心配置:
-
x-dead-letter-exchange 指定死信交换机
-
x-dead-letter-routing-key 指定死信路由key
死信队列例子
1. 测试消息有效期(per-message TTL)过期
1.1 RabbitMQConfig配置文件
@Bean
public Queue ttlDirectQueue(){
Map<String,Object> map=new HashMap<>();
map.put("x-message-ttl",10000);
map.put("x-dead-letter-exchange",DLX_DIRECT_EXCHANGE);
map.put("x-dead-letter-routing-key",DLX_DIRECT_ROUTINGKEY);
map.put("x-max-length",100);
return new Queue(TTL_DIRECT_QUEUE,true,false,false,map);
}
/**
* DLX_direct交换机名称
*/
public static final String DLX_DIRECT_EXCHANGE="dlxldirectExchange";
/**
* dlx_direct队列名称
*/
public static final String DLX_DIRECT_QUEUE="dlxldirectQueue";
/**
* dlx_direct路由Key
*/
public static final String DLX_DIRECT_ROUTINGKEY="dlx_directRoutingKey";
/**
* 定义一个DLX direct交换机
* @return
*/
@Bean
public DirectExchange dlxDirectExchange(){
return new DirectExchange(DLX_DIRECT_EXCHANGE);
}
/**
* 定义一个DLX direct队列
* @return
*/
@Bean
public Queue dlxDirectQueue(){
return new Queue(DLX_DIRECT_QUEUE);
}
/**
* dlx定义一个队列和交换机的绑定
* @return
*/
@Bean
public Binding dlxDirectBinding(){
return BindingBuilder.bind(dlxDirectQueue()).to(dlxDirectExchange()).with(DLX_DIRECT_ROUTINGKEY);
}
1.2 producer
1.3 启动producer服务
控制台:
10秒后,消息进入了dlxldirectQueue,如下图:
2. 测试消息超过队列长度限制而被丢弃
2.1 修改RabbitMQConfig配置
2.2 发送20条消息
可以发现,10条消息进入了ttldirectQueue, 另外10条进入了dlxldirectQueue,如下图:
3. 测试消息拒签
消息被消费者使用basic.reject或basic.nack方法并且requeue参数值设置为false的方式进行消息确认(negatively acknowledged)
3.1 修改RabbitMQConfig配置
启动producer服务后,
由于队列长度限制最多为100,所以剩下100条消息进入了dlxldirectQueue死信队列,如下图:
3.2 消费者拒签
启动consumer服务后,由于剩下的100条消息发生了拒签,所以也进入了死信队列: