延遲隊列的本質用的到時死信,如下情況下消息會變爲死信
1
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秒。