RabbitMQ(四)死信队列和延迟队列

在定义业务队列的时候,要考虑指定一个死信交换机,死信交换机可以和任何一个普通的队列进行绑定,实际上就是设置某个队列的属性,然后在业务队列出现死信的时候就会将数据发送到死信队列。

进入死信队列的情况:

  • 消息被拒绝(basic.reject/ basic.nack)并且不再重新投递 requeue=false
  • 消息超期 (rabbitmq Time-To-Live -> messageProperties.setExpiration())
  • 队列超载。比如,发送邮件队列的长度已满

变成了 “死信” 后 被重新投递(publish)到另一个Exchange 该Exchange 就是DLX
然后该Exchange 根据绑定规则 转发到对应的 队列上 ,监听该队列 就可以重新消费。
RabbitMQ(四)死信队列和延迟队列_第1张图片
配置文件:



        
        

        
        

        
        

        
        
            
                
                
            
        
        
        
                
                          
                 
        

    
    
    
    
        
             
        
    

        
        
        
        

        
            
            
        


此时队列情况:
RabbitMQ(四)死信队列和延迟队列_第2张图片
正常消费者:

@Override
public void onMessage(Message message, Channel channel) throws Exception {
    try {
        String messageStr = new String(message.getBody());
        System.out.println("消费者接收到信息 : " + messageStr);
        if (messageStr.equals("hello")) {
            //告诉服务器收到这条消息 已经被我消费了 可以在队列删掉 这样以后就不会再发了 否则消息服务器以为这条消息没处理掉 后续还会在发
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }else{
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false, false);
        }
    } catch (Exception e) {
        e.printStackTrace();//TODO 业务处理
        //丢弃这条消息
        channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
    }
}

死信消费者:

@Service("deadQueueListener")
public class DeadQueueListener implements ChannelAwareMessageListener {
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        try {
            String messageStr = new String(message.getBody());
            System.out.println("【死信队列】——消费者接收到信息 : " + messageStr);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            e.printStackTrace();//TODO 业务处理
            //丢弃这条消息
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
        }
    }
}

测试:

http://localhost:8081/test/send?exchange=exchangeTest&key=queueTestKey&message=helloaaa

RabbitMQ(四)死信队列和延迟队列_第3张图片

延迟队列

场景:三方支付,扫码支付调用上游的扫码接口,当扫码有效期过后去调用查询接口查询结果。实现方式:每当一笔扫码支付请求后,立即将此订单号放入延迟队列中,队列过期时间为二维码有效期,此队列没有设置消费者,过了有效期后消息会重新路由到指定的的队列,有消费者去执行订单查询。
RabbitMQ本身没有直接支持延迟队列功能,但是可以通过以下特性模拟出延迟队列的功能。 但是我们可以通过RabbitMQ的两个特性来曲线实现延迟队列:Time To Live(TTL) 和 Dead Letter Exchanges(DLX)
RabbitMQ可以针对Queue和Message设置 x-message-tt,来控制消息的生存时间,如果超时,则消息变为dead letter(死信)。
配置文件:



    
        
        
        
            10000
        
    

并且把消费者去掉


    
    

发送消息:

http://localhost:8081/test/send?exchange=exchangeTest&key=queueTestKey&message=hello

结果:
RabbitMQ(四)死信队列和延迟队列_第4张图片

你可能感兴趣的:(rabbitMQ,RabbitMQ)