一、什么是死信交换机
1.消息被拒绝,并且设置为requeue参数为false
2.消息过期(默认情况下Rabbit中的消息不过期,但是可以设置队列的过期时间和消息的过期时间以上达到消息过期的效果)
3.队列达到最大长度(一般当设置了最大队列长度或大小并达到最大值时)
当满足上面三种情况时,消息会变成死信消息,并通过死信交换机投递到相应的队列中
二、代码实例
1.编写配置类,定义普通以及死信交换机和队列并各自绑定
package com.example.provider.mq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("all")
@Slf4j
@Configuration
public class deadConfig {
/**
* 正常队列
* @return
*/
@Bean
public Queue normalQueue(){
Map<String,Object> map=new HashMap();
map.put("x-message-ttl", 5000);//message在该队列queue的存活时间最大为10秒
map.put("x-dead-letter-exchange", "deadExchange");//x-dead-letter-exchange参数
//是设置该队列的死信交换器(DLX)
map.put("x-dead-letter-routing-key","DD");//x-dead-letter-routing-key
//参数是给这个DLX指定路由键
return new Queue("normalQueue",true,false,false,map);
}
/**
* 死信队列
* @return
*/
@Bean
public Queue deadQueue(){
return new Queue("deadQueue",true);
}
/**
* 直连交换机
* @return
*/
@Bean
public DirectExchange normalExchange(){
return new DirectExchange("normalExchange");
}
/**
* 死信交换机
* @return
*/
@Bean
public DirectExchange deadExchange(){
return new DirectExchange("deadExchange");
}
/**
* 普通队列与交换机绑定
* @return
*/
@Bean
public Binding binding(){
return BindingBuilder.bind(normalQueue()).to(normalExchange()).with("CC");
}
/**
* 死信队列与死信机绑定
* @return
*/
@Bean
public Binding deadbinding(){
return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("DD");
}
}
2.controller层模拟订单发出
@RequestMapping("/sendNormal") public String sendNormal(){ rabbitTemplate.convertAndSend("normalExchange","CC","订单1111"); return "yes"; }
3.运行结果
表示接收到一条消息
5秒后消息消失变成0,因为5秒后过期了
然后由死信交换机传到死信队列中
4.在消费者中创建死信队列的接收类
package com.example.consumer.mq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@SuppressWarnings("all")
@RabbitListener(queues ="deadQueue")
@Slf4j
public class DeadReceiver {
@RabbitHandler
public void process(String message){
log.warn("订单过期"+message);
}
}
5.启动后死信队列的消息被接收