RabbitMQ高级应用之消费端限流策略basicQos详解

 更新时间:2023年08月28日 10:08:26   作者:疯狂的帆  
这篇文章主要介绍了RabbitMQ高级应用之消费端限流策略basicQos详解,高并发情况下,队列里面一瞬间就就积累了上万条数据,但是消费者无法同时处理这么多请求,这种场景下我们就需要对消费端进行限流,需要的朋友可以参考下

业务场景

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

但是客户端是没有办法同时处理这么多数据的,结果就是消费者(客户端)挂掉了…

这种场景下我们就需要对消费端进行限流

限流策略实现

限流策略关键代码:

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, 5, 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);
    }
}

运行结果

在这里插入图片描述

在这里插入图片描述

小结

  1. 限流的核心代码就是 channel.basicQos();
  2. 限流情况 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:表示当前通道的所有消费者都应用这个限流策略

到此这篇关于RabbitMQ高级应用之消费端限流策略basicQos详解的文章就介绍到这了,更多相关RabbitMQ消费端限流策略basicQos内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java自定义Enum的实现示例

    Java自定义Enum的实现示例

    Java中的自定义Enum类型是一种特殊的类,用于表示固定数量的常量值,本文主要介绍了Java自定义Enum的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • Spring Boot启动时调用自己的非web逻辑

    Spring Boot启动时调用自己的非web逻辑

    在spring Boot中,有些代码是WEB功能,例如API等,但是有些逻辑是非WEB,启动时就要调用并持续运行的,该如何加载自己的非WEB逻辑呢,下面通过实例代码给大家讲解,一起看看吧
    2017-07-07
  • Java中的线程死锁是什么?如何避免?

    Java中的线程死锁是什么?如何避免?

    这篇文章主要介绍了Java中线程死锁的相关资料,以及避免死锁的方法,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2020-09-09
  • 基于SpringBoot构建电商秒杀项目代码实例

    基于SpringBoot构建电商秒杀项目代码实例

    这篇文章主要介绍了基于SpringBoot构建电商秒杀项目代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 详解如何在SpringBoot中使用WebMvc

    详解如何在SpringBoot中使用WebMvc

    Spring Boot 是一个快速、简单的开发框架,在 Spring Boot 中,我们可以使用 WebMvc 来构建 Web 应用程序,所以本文就来讲讲如何在SpringBoot中使用WebMvc吧
    2023-06-06
  • java中不同版本JSONObject区别小结

    java中不同版本JSONObject区别小结

    本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • Java获取磁盘空间的两种代码示例

    Java获取磁盘空间的两种代码示例

    这篇文章主要介绍了Java获取磁盘空间的两种代码示例,没什么事的时候可以拿来玩玩,需要的朋友参考下。
    2017-11-11
  • 基于Java8 函数式接口理解及测试

    基于Java8 函数式接口理解及测试

    下面小编就为大家带来一篇基于Java8 函数式接口理解及测试。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • 解决idea中yml文件图标问题及自动提示失效的情况

    解决idea中yml文件图标问题及自动提示失效的情况

    这篇文章主要介绍了解决idea中yml文件图标问题及自动提示失效的情况,具有很好的价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Spring覆盖容器中Bean的注解如何实现@OverrideBean

    Spring覆盖容器中Bean的注解如何实现@OverrideBean

    文章介绍了在项目开发中如何通过偷梁换柱的方式重写Spring容器中的内置Bean,并指出了需要注意的两点:1. 对应的Bean应基于接口注入;2. 如果不是基于接口注入,可以使用同包名同类名的方式重写(可能存在潜在问题,不推荐),文章还强调了“基于接口编程”的好处
    2025-01-01

最新评论