RabbitMQ的死信队列机制

一、死信队列

死信指的是无法被消费的消息,由于消息TTL过期队列达到最大长度消息被拒绝等原因,导致队列中一些消息无法被消费,这样的消息如果没有进行后续的处理,就会变成死信。为了保证消息数据不丢失,需要使用死信队列机制。

二、死信队列的实现

在这里插入图片描述

1、消息 TTL 过期

普通队列消费者Consumer01

public class Consumer01 {

    //不同交换机
    public static final String NORMAL_EXCHANGE = "normal_exchange";

    //死信交换机
    public static final String DEAD_EXCHANGE = "dead_exchange";

    //普通队列
    public static final String NORMAL_QUEUE = "normal_queue";

    //死信队列
    public static final String DEAD_QUEUE = "dead_queue";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        //声明普通交换机和死信交换机
        channel.exchangeDeclare(NORMAL_EXCHANGE, BuiltinExchangeType.DIRECT);
        channel.exchangeDeclare(DEAD_EXCHANGE, BuiltinExchangeType.DIRECT);
        //声明普通队列
        Map<String, Object> arguments = new HashMap<>();
        //arguments.put("x-message-ttl","10000"); //设置TTL过期时间为10s
        arguments.put("x-dead-letter-exchange", DEAD_EXCHANGE);  //给普通队列设置死信交换机
        arguments.put("x-dead-letter-routing-key", "lisi");  //设置死信交换机的routingKey
        channel.queueDeclare(NORMAL_QUEUE, false, false, false, arguments);
        //声明死信队列
        channel.queueDeclare(DEAD_QUEUE, false, false, false, null);
        //绑定普通队列和普通交换机
        channel.queueBind(NORMAL_QUEUE, NORMAL_EXCHANGE, "zhangsan");
        //绑定死信队列和死信交换机
        channel.queueBind(DEAD_QUEUE, DEAD_EXCHANGE, "lisi");
        System.out.println("Consumer01等待接收消息......");

        //声明接收消息回调函数 和 取消消息消费时的回调函数
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            String msg = new String(message.getBody(), "UTF-8");
            System.out.println("Consumer01接收消息:" + msg);
        };

        CancelCallback cancelCallback = (consumerTag) -> {
            System.out.println("取消消息消费");
        };

        channel.basicConsume(NORMAL_QUEUE, true, deliverCallback, cancelCallback);
    }
}

死信队列消费者Consumer02

public class Consumer02 {

    //死信队列
    public static final String DEAD_QUEUE = "dead_queue";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();

        System.out.println("Consumer02等待接收消息......");

        //声明接收消息回调函数 和 取消消息消费时的回调函数
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            String msg = new String(message.getBody(), "UTF-8");
            System.out.println("Consumer02接收消息:" + msg);
        };

        CancelCallback cancelCallback = (consumerTag) -> {
            System.out.println("取消消息消费");
        };

        channel.basicConsume(DEAD_QUEUE, true, deliverCallback, cancelCallback);
    }
}

生产者设置TTL消息过期时间为10s

public class Producer {
    public static final String NORMAL_EXCHANGE = "normal_exchange";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();

        //设置TTL消息过期时间
        AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().expiration("10000").build();

        for (int i = 0; i <= 10; i++) {
            String message = "info" + i;
            channel.basicPublish(NORMAL_EXCHANGE, "zhangsan", properties, message.getBytes("UTF-8"));
        }
    }
}

在普通队列挂掉了的情况下,由于设置TTL为10s,超时之后消息会通过死信交换机被发送到死信队列
在这里插入图片描述
死信队列消费者会接收了死信队列的消息
在这里插入图片描述

2、队列达到最大长度

普通队列长度设置为5,超过最大长度的消息会被放到死信队列中
在这里插入图片描述
生产者一共发送了11条消息,5条消息在普通队列,6条消息在死信队列
在这里插入图片描述

3、消息被拒绝

如果普通消费者拒绝掉普通队列里面的消息,消息也会被放到死信队列中
在这里插入图片描述
普通消费者拒绝的消息被转发到死信队列
在这里插入图片描述
在这里插入图片描述
拒绝的消息被死信消费者接收
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值