1.什么是死信交换机
当一个队列中消息满足下列情况之一时,就可以成为死信
1.消费者消费失败
2.消息超时无人消费
3.队列消息满了,无法投递
如果队列配置了dead-letter-exchange
属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机称为死信交换机。以下代码核心思想是,利用超时时间,使消息成为死信投递到死信交换机,并配置消费者监听死信交换机,从而达到延迟消费
2.利用超时时间实现延迟消息
2.1编写配置类,声明队列和交换机
@Configuration
public class CommonConfig {
/**
* 声明队列
* @return
*/
@Bean
public Queue ttlQueue(){
return QueueBuilder.durable("ttl.queue") // 队列名称
.ttl(10000) // 设置队列的超时时间,10秒
.deadLetterExchange("dl.ttl.direct") // 队列绑定死信交换机
.build();
}
/**
* 声明交换机
* @return
*/
@Bean
public DirectExchange ttlExchange(){
return new DirectExchange("ttl.direct");
}
/**
* 队列和交换机绑定
* @return
*/
@Bean
public Binding ttlBinding(){
return BindingBuilder.bind(ttlQueue()).to(ttlExchange()).with("ttl");
}
}
2.2接收死信交换机的消息
@Component
@Slf4j
public class SpringRabbitListener {
/**
* 声明死信交换机和队列
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue("dl.ttl.queue"), //声明一个队列名称
exchange = @Exchange(name = "dl.ttl.direct"),//声明死信交换机名称
key = "ttl"
))
public void listenDlQueue(String msg) {
log.error("接收到了死信队列消息,消息为:" + msg);
}
}
2.3发送消息
@Test
public void testTTLMsg() {
// 创建消息
Message message = MessageBuilder
.withBody("hello, ttl message".getBytes(StandardCharsets.UTF_8))
.setExpiration("5000")
.build();
// 消息ID,需要封装到CorrelationData中
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
// 发送消息
rabbitTemplate.convertAndSend("ttl.direct", "ttl", message, correlationData);
log.debug("发送消息成功");
}
}
3.测试
成功发送,注意发送时间
再去消费端看看,正好是5秒
注意!在队列、消息中都能设置超时时间,并可以同时设置,但生效以时间短的为准