延迟队列的本质用的到时死信,如下情况下消息会变为死信
1
被
拒
绝
、
n
a
c
k
并
且
没
有
重
新
入
队
的
消
息
\color{#FF0000}{被拒绝、nack并且没有重新入队的消息}
被拒绝、nack并且没有重新入队的消息
2 消息过期
3 队列达到了最大长度。
成为死信的消息可以进入死信交换机,然后进入另外一个队列中。
两个交换器和队列如下
//--------------------------死信队列测试------------------
public static final String NORMAL_QUEUE_NAME="queue.normal";
public static final String NORMAL_EXCHANGE_NAME="exchange.normal";
public static final String NORMAL_ROUTING_KEY ="normal.routing.key";
@Bean
public Queue normalQueue(){
//设置死信队列
Map<String,Object> arguments=new HashMap<>();
arguments.put("x-dead-letter-exchange",DEAD_EXCHANGE_NAME);
arguments.put("x-dead-letter-routing-key",DEAD_LETTER_ROUTING_KEY);
//设置过期时间为10秒
arguments.put("x-message-ttl",10000);
return new Queue(NORMAL_QUEUE_NAME, true, false, false,arguments);
}
@Bean
public DirectExchange normalExchange(){
return new DirectExchange(NORMAL_EXCHANGE_NAME,true,false);
}
@Bean
public Binding normalExchangeBindQueue(){
return BindingBuilder.bind(normalQueue())
.to(normalExchange())
.with(NORMAL_ROUTING_KEY);
}
public static final String DEAD_LETTER_ROUTING_KEY ="dead.letter.test";
public static final String DEAD_EXCHANGE_NAME="exchange.dlx";
public static final String DEAD_QUEUE_NAME="queue.dlx";
@Bean
public Queue deadQueue(){
return new Queue(DEAD_QUEUE_NAME);
}
@Bean
public DirectExchange deadExchange(){
return new DirectExchange(DEAD_EXCHANGE_NAME,true,false);
}
/**
* 死信队列与交换器绑定
* @return
*/
@Bean
public Binding deadExchangeBindQueue(){
return BindingBuilder.bind(deadQueue())
.to(deadExchange())
.with(DEAD_LETTER_ROUTING_KEY);
}
发送
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendMsg(){
//发送Map对象
Map<String,Object> map=new HashMap<>();
map.put("id",1);
map.put("username","张三");
map.put("password","123");
//设置消息唯一id
CorrelationData correlationData=new CorrelationData();
correlationData.setId(1+"");
logger.info("发送时间{}",System.currentTimeMillis());
rabbitTemplate.convertAndSend(RabbitMQConfig.NORMAL_EXCHANGE_NAME,//exchange
RabbitMQConfig.NORMAL_ROUTING_KEY,//rountingKey
map,//
correlationData);
}
接收方:
/**
* 死信队列
* @param user
* @param headers
* @param channel
* @throws IOException
*/
@RabbitListener(queues = "queue.dlx")
@RabbitHandler
public void onUserInfoMessage(@Payload Map user,
@Headers Map<String, Object> headers, Channel channel) throws IOException {
//消费者操作
logger.info("接收到的消息【{}】", user.toString());
logger.info("接受到消息的时间{}",System.currentTimeMillis());
//确认签收
Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
channel.basicAck(deliveryTag, false);
}
控制台打印的两个时间正好相差10秒。