Rabbitmq 死信队列

        死信指的是无法被消费的消息。这些消息因为一些如网络超时等原因,导致无法被消费,就成了死信消息。所以为了保证这些数据不丢失,就有了死信队列,专门对死信消息进行处理。


  • 工具类

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class RabbitMQUtils {

    // 创建连接mq的链接工厂对象
    private static  ConnectionFactory connectionFactory;

    static {

        connectionFactory = new ConnectionFactory();
        // 设置rabbitmq服务器所在的ip port
        connectionFactory.setHost("192.168.1.100");
        connectionFactory.setPort(5672);
        // 设置rabbitmq所在的虚拟主机
        connectionFactory.setVirtualHost("/");
        // 设置rabbitmq所在服务的用户名 密码
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

    }

    // 定义提供链接对象的方法
    public static Connection getConnection(){


            try {
                return connectionFactory.newConnection();
            } catch (Exception e) {
                e.printStackTrace();
            }


        return null;
    }

    // 关闭通道和链接的方法
    public static void closeChannelAndConnection(Channel channel, Connection connection){
        try {
            if(channel!=null) channel.close();
            if(connection!=null) connection.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

  • 生产者

import cn.my.utils.RabbitMQUtils;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

import java.io.IOException;

public class DeadProduct {
    //正常交换机
    public static String NORMAL_EXCHANGE = "NORMAL_EXCHANGE01";
    //正常routingkey
    public static String NORMAL_ROUTINGKEY = "normalQueue01";

    public static void main(String[] args) throws IOException {
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(NORMAL_EXCHANGE, "direct");

        AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().expiration("10000").build();

        String message = "Test dead message";

        for (int i = 1; i < 11; i++) {
            channel.basicPublish(NORMAL_EXCHANGE, NORMAL_ROUTINGKEY, properties, message.getBytes());
        };

        System.out.println("发送消息");
    }

}

  • 正常队列

import cn.my.utils.RabbitMQUtils;
import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.HashMap;

public class DeadConsumer01 {
    //正常交换机
    public static String NORMAL_EXCHANGE = "NORMAL_EXCHANGE01";
    //死信交换机
    public static String DEAD_EXCHANGE = "DEAD_EXCHANGE01";
    //正常队列
    public static String NORMAL_QUEUE = "NORMAL_QUEUE01";
    //死信队列
    public static String DEAD_QUEUE = "DEAD_QUEUE01";
    //正常 routingkey
    public static String NORMAL_ROUTINGKEY = "normalQueue01";
    //死信routingkey
    public static String DEAD_ROUTINGKEY = "deadQueue01";


    public static void main(String[] args) throws IOException {
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();

        //正常交换机
        channel.exchangeDeclare(NORMAL_QUEUE,"direct");
        //死信交换机
        channel.exchangeDeclare(DEAD_EXCHANGE,"direct");

        //声明死信队列
        channel.queueDeclare(DEAD_QUEUE,false,false,false,null);

        //设置参数
        HashMap<String, Object> arguments = new HashMap<>();
        //设置死信交换机
        arguments.put("x-dead-letter-exchange", DEAD_EXCHANGE);
        //设置死信RoutingKey
        arguments.put("x-dead-letter-routing-key", DEAD_ROUTINGKEY);
        //设置正常队列长度
        arguments.put("x-max-length", 6);
        //设置过期时间,10s(一般不在这里设置,而是在生产者端配置,这样子过期时间可以由生产者随意改动)
        //arguments.put("x-message-ttl", "10000");

        //声明普通队列
        channel.queueDeclare(NORMAL_QUEUE,false,false,false,arguments);

        //绑定普通交换机和队列
        channel.queueBind(NORMAL_QUEUE,NORMAL_EXCHANGE,NORMAL_ROUTINGKEY);
        //绑定死信交换机和队列
        channel.queueBind(DEAD_QUEUE,DEAD_EXCHANGE,DEAD_ROUTINGKEY);

        //消费者成功消费时候的回调方法
        DeliverCallback deliverCallback = (s, delivery) -> {
            System.out.println("  不想接受,拒绝!");
            channel.basicReject(delivery.getEnvelope().getDeliveryTag(),false);
        };

        //消费者取消消费的回调方法
        CancelCallback cancelCallback = s -> System.out.println("消费者取消消息的回调方法:"+s);

        channel.basicConsume(NORMAL_QUEUE,false,deliverCallback,cancelCallback);

        System.out.println("正常队列准备消费消息......");

    }

}

  • 死信队列

import cn.my.utils.RabbitMQUtils;
import com.rabbitmq.client.*;

import java.io.IOException;

public class DeadConsumer02 {
    //死信队列
    public static String DEAD_QUEUE = "DEAD_QUEUE01";

    public static void main(String[] args) throws IOException {
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();

        DeliverCallback deliverCallback = new DeliverCallback() {
            @Override
            public void handle(String s, Delivery delivery) throws IOException {
                System.out.println("死信队列消费:  " + new String(delivery.getBody()));
            }
        };

        CancelCallback cancelCallback = new CancelCallback() {
            @Override
            public void handle(String s) throws IOException {
                System.out.println("消费者取消消费的回调方法 = " + s);
            }
        };

        channel.basicConsume(DEAD_QUEUE,true, deliverCallback, cancelCallback);
        System.out.println("死信队列等待消费···");
    }
}

正常队列拒绝接受消息后,死信队列才会消费消息。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值