RabbitMQ预取值

该博客探讨了在RabbitMQ中,如何设置消费者C1和C2分别接收不同数量的消息,以及如何导致消息堆积。通过DirectSend类,生产者发送消息到exchange,而DirectRecv和DirectRecv2类作为消费者,设置不同的prefetchCount来控制接收消息的数量。消费者C2的处理时间较长,可能导致消息堆积在信道。最终关注点在于消费者C2是否能成功消费到5条消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

假设生产者发送 11.22.33.44.55.66.77 条消息, 我们可以指定消费者C1接受2条消息,消费者C2接受5条消息。

最后的结果是消息堆积在信道,是说堆积在信道中最多有几条

public class DirectSend {
    private static final String EXCHANGE_NAME = "test_exchange_direct";
    private static final String TASK_QUEUE_NAME = "task_queue_name";
 
    private static final boolean durable = false;
    public static void main(String[] argv) throws Exception {
        // 获取到连接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
 
 
        channel.queueDeclare(TASK_QUEUE_NAME, durable, false, false, null);
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            String message = scanner.next();
            //设置生产者发送消息为持久化消息(要求保存到磁盘上)保存在内存中
            channel.basicPublish("", TASK_QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"));
            System.out.println("生产者发出消息");
        }
        channel.close();
        connection.close();
    }
}
public class DirectRecv {
    private final static String QUEUE_NAME = "test_queue_direct_1";
 
    private final static String EXCHANGE_NAME = "test_exchange_direct";
    private static final String TASK_QUEUE_NAME = "task_queue_name";
 
    public static void main(String[] argv) throws Exception {
 
        // 获取到连接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
 
        System.out.println("c1 等待接收消息处理时间较短");
 
        DeliverCallback deliverCallback = (consumerTag, message)->{
            try {
                Thread.sleep(1000L);
            }catch (Exception e){
                e.printStackTrace();
            }
 
            System.out.println("接收到的消息:" + new String(message.getBody(),"UTF-8"));
 
            //手动应答
            /**
             * 1、消息的标记 tag
             * 2、是否批量应答 false : 不批量应答信道中的小, true:批量
             */
            channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
        };
 
        // 这只不公平分发
        int prefetchCount = 2;//默认是1
        channel.basicQos(prefetchCount);
 
        //采用手动应答
        boolean autoAct = false;
        channel.basicConsume(TASK_QUEUE_NAME, autoAct,deliverCallback,(consumerTag -> {
            System.out.println(consumerTag + "消费者消息取消接口回调逻辑");
        }));
    }
}
public class DirectRecv2 {
    private final static String QUEUE_NAME = "test_queue_direct_1";
 
    private final static String EXCHANGE_NAME = "test_exchange_direct";
    private static final String TASK_QUEUE_NAME = "task_queue_name";
 
    public static void main(String[] argv) throws Exception {
 
        // 获取到连接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
 
        System.out.println("c1 等待接收消息处理时间较短");
 
        DeliverCallback deliverCallback = (consumerTag, message)->{
            try {
                Thread.sleep(30000L);
            }catch (Exception e){
                e.printStackTrace();
            }
 
            System.out.println("接收到的消息:" + new String(message.getBody(),"UTF-8"));
 
            //手动应答
            /**
             * 1、消息的标记 tag
             * 2、是否批量应答 false : 不批量应答信道中的小, true:批量
             */
            channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
        };
 
        // 这只不公平分发
        int prefetchCount = 5;//默认是1
        channel.basicQos(prefetchCount);
 
        //采用手动应答
        boolean autoAct = false;
        channel.basicConsume(TASK_QUEUE_NAME, autoAct,deliverCallback,(consumerTag -> {
            System.out.println(consumerTag + "消费者消息取消接口回调逻辑");
        }));
 
    }
 
}

 所以执行的结果,我们需要看消费者2是否消费到了5条数据

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值