RabbitMQ从零开始学(三)通信模型之Work型—channel.basicQos()

work模型

称为工作队列或者竞争消费者模式,多个消费者消费的数据之和才是原来队列中的所有数据,适用于流量的消峰
在这里插入图片描述

生产者的编写

public class Producer {
    private static final String QUEUE_NAME = "queue_work_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, ("work消息模型:"+i).getBytes());
        }
        channel.close();
        connection.close();
    }
}

消费者

// 消费者1
public class Consumer {
    private static final String QUEUE_NAME = "queue_work_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);
        // channel.basicQos(1);
        // 声明消费者
        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
public class Consumer2 {
    private static final String QUEUE_NAME = "queue_work_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);
        // channel.basicQos(1);
        // 声明消费者
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者2接受到的消息是:" + new String(body));
                //进行手动应答
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        // 绑定消费者
        channel.basicConsume(QUEUE_NAME, false, defaultConsumer);
    }
}

测试结果

在这里插入图片描述
在这里插入图片描述

运行的时候可以看出 消费者1 几乎是瞬间完成,消费者2则是慢慢吞吞的运行完毕,消费者1大量时间处于空闲状态,消费者2则一直忙碌。这显然是不适用于实际开发中。

我们需要遵从一个原则,就是 能者多劳 ,消费越快的人,消费的越多。

能者多劳

修改消费者的代码,两个都添加上 以下代码

channel.basicQos(1);

运行结果:

在这里插入图片描述
在这里插入图片描述

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
    • 默认值:0
  • param2:prefetchCount,服务器一次请求将传递的最大邮件数,如果没有限制,则为0
    • 调用此方法时,该值必填。默认值:0
  • param3:global,是否将设置应用于整个频道,而不是每个消费者
    • 默认值:false,应用于本身(一个消费者)
    • true:应用于整个频道

RabbitMQ通讯模型系列

RabbitMQ从零开始学(二)—通信模型之HelloWorld型—channel方法参数详解
RabbitMQ从零开始学(四)—通信模型之发布订阅模型—channel.exchangeDeclare()—channel.queueBind()
RabbitMQ从零开始学(五)—通信模型之路由模型(direct)
RabbitMQ从零开始学(六)—通信模型之topic模型—通信模型总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值