RabbitMQ高级应用-消费端限流策略(basicQos)

本文介绍了在高并发场景下,如何使用RabbitMQ的消费者限流策略避免客户端因大量消息涌入而崩溃。通过设置`channel.basicQos()`方法,调整`prefetchCount`参数限制一次性推送的消息数量,实现消费者端的流量控制。示例中展示了生产者和两个不同配置的消费者,消费者2通过设置`basicQos`实现了限流,确保不超过10个消息同时处理,有效防止了消费者挂掉的问题。
摘要由CSDN通过智能技术生成

业务场景
高并发情况下,队列里面一瞬间就就积累了上万条数据,但是消费者无法同时处理这么多请求,这个时候当我们打开客户端,瞬间就有巨量的信息给推送过来、但是客户端是没有办法同时处理这么多数据的,结果就是消费者(客户端)挂掉了…

这种场景下我们就需要对消费端进行限流,防止客户端积累过多奔溃

限流策略实现
限流策略关键代码:channel.basicQos();

编写生产者
// 生产者

public class Producer {
    private static final String QUEUE_NAME = "queue_limit_1";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        for (int i = 0; i < 100; i++) {
            channel.basicPublish("", QUEUE_NAME, null, ("消费端限流策略—测试数据:" + i).getBytes());
        }
        channel.close();
        connection.close();
    }
}

编写消费者1
// 消费者1

public class Consumer {
    private static final String QUEUE_NAME = "queue_limit_1";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1接收到信息:" + new String(body));
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(QUEUE_NAME, false, defaultConsumer);
    }
}

编写消费者2

// 消费者2
public class Consumer2 {
    private static final String QUEUE_NAME = "queue_limit_1";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        /**  设置限流机制
         *  param1: prefetchSize,消息本身的大小 如果设置为0  那么表示对消息本身的大小不限制
         *  param2: prefetchCount,告诉rabbitmq不要一次性给消费者推送大于N个消息
         *  param3:global,是否将上面的设置应用于整个通道,false表示只应用于当前消费者
         */
        channel.basicQos(0, 10, false);
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者2接收到信息:" + new String(body));
                channel.basicAck(envelope.getDeliveryTag(), false);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        channel.basicConsume(QUEUE_NAME, false, defaultConsumer);
    }
}

运行结果
在这里插入图片描述
在这里插入图片描述

小结
限流的核心代码就是channel.basicQos();
限流情况 ack 不能设置自动签收,一定要手动签收
channel.basicQos()

/**
     * @param prefetchSize maximum amount of content (measured in
     * octets) that the server will deliver, 0 if unlimited
     * @param prefetchCount maximum number of messages that the server
     * will deliver, 0 if unlimited
     * @param global true if the settings should be applied to the
     * entire channel rather than each consumer
     */
    void basicQos(int prefetchSize, int prefetchCount, boolean global) throws IOException;

该方法的作用是:进行消费端的限流

param1:prefetchSize,消息本身的大小 如果设置为0 那么表示对消息本身的大小不限制
param2:prefetchCount,告诉rabbitmq不要一次性给消费者推送大于N个消息
param3:global,是否将上面的设置应用于整个通道
false:表示只应用于当前消费者
true:表示当前通道的所有消费者都应用这个限流策略

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值