RabbitMQ---死信交换机

发布时间 2023-05-26 15:04:04作者: wzh_Official

什么是死信交换机?
要先解释一下什么是死信:当一个队列中的消息满足下列情况之一。就可称为死信。

  • 消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false
  • 消息是一个过期消息,超时无人消费
  • 要投递的队列消息满了,无法投递
    如果这个包含死信的队列配置了dead-letter-exchange属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机称为死信交换机。

死信交换机的用处
死信交换机主要用于延时发送信息,在网上买东西时,订单支付时间就可以使用到延时交换机。

TTL
一个队列中的消息如果超时未消费,则会变为死信,超时分为两种情况:

  • 消息所在的队列设置了超时时间
  • 消息本身设置了超时时间

接收死信的步骤:

  • 在consumer服务中,定义一个新的消费者,并且声明 死信交换机、死信队列
点击查看代码
@Slf4j
@Component
public class TTLListener {
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "dl.queue",durable = "true"),
            exchange = @Exchange(name = "wzh.dl",type = ExchangeTypes.DIRECT),
            key = "dl"
    ))
    public void ttlListerer(String msg){
        log.info("接收到 dl.ttl.queue的延迟消息:{}", msg);
    }
}
  • 声明一个队列,并且指定TTL
点击查看代码
@Configuration
public class TTLConfig {
    @Bean
    public Queue ttlQueue(){
        return QueueBuilder.durable("ttl.queue")  //指定队列名称,并持久化
                .ttl(10000)  //设置队列的超时时间,10秒
                .deadLetterExchange("wzh.dl")  //指定死信交换机
                .deadLetterRoutingKey("dl")  //指定死信交换机路由的key
                .build();
    }
    @Bean
    public DirectExchange ttlExchange(){
        return new DirectExchange("wzh.ttl");
    }
    @Bean
    public Binding ttlBinding(){
        return BindingBuilder.bind(ttlQueue()).to(ttlExchange()).with("ttl");
    }
}
  • 发送消息,但是不要指定TTL
点击查看代码
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class TTlQueue {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Test
    public void ttlTest(){
        String msg="Hello,I'm dlExchange";
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("wzh.ttl","ttl",msg,correlationData);
        log.info("消息发送成功");
    }
}
  • 查看最终效果

    发送消息的十秒后消费者才会接收到消息。