9.不公平分发&预取值

在之前的工作队列模式中,对于多个消费者,也就是多个工作线程采用的是轮训分发的方式消费消息。

轮训分发策略并不是很好,比如两个消费者在处理任务时候,其中一个消费者处理速度快,另一个消费者处理速度慢。采用轮训分发就会造成处理速度快的消费者有很大一部分时间处于空闲状态。应该遵循能者多劳的原则。

不公平分发

设置参数 channel.basicQos(1); 1表示不公平分发。0表示轮训分发,默认值。

这个参数应该设置在消费方,由消费方决定是否使用非公平分发。

package com.xkj.org.mq.ack;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.xkj.org.utils.RabbitMQUtil;

import java.io.IOException;

public class Worker01 {

    private static final String QUEUE_NAME = "ack_queue";

    public static void main(String[] args) throws IOException {
        Channel channel = RabbitMQUtil.getChannel();
        //设置不公平分发
        channel.basicQos(1);
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("接受到消息:"+ new String(message.getBody(), "UTF-8"));
            //第一个参数,消息标记tag
            //第二个参数,false非批量应答
            channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
        };

        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("work1 消息消费被中断");
        };
        System.out.println("worker1等待1s接收消息.......");
        //设置手动应答
        channel.basicConsume(QUEUE_NAME, false, deliverCallback, cancelCallback);
    }

}

预取值

指定每个消费者取多少条消息。

 prefetch代表信道channel中放的消息数量。

channel.basicQos(prefetch),  prefetch值为0表示轮训分发,1表示非公平分发,如果>1表示预期值prefetch。

设置在消费者端,消费者A预期值2条,消费者B预取值5条,生产者发送7条消息。表示的是消息堆积在信道里的数量

package com.xkj.org.mq.ack;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.xkj.org.utils.RabbitMQUtil;

import java.io.IOException;

public class Worker01 {

    private static final String QUEUE_NAME = "ack_queue";

    public static void main(String[] args) throws IOException {
        Channel channel = RabbitMQUtil.getChannel();
        //设置不公平分发,预期值2
        channel.basicQos(2);
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("接受到消息:"+ new String(message.getBody(), "UTF-8"));
            //第一个参数,消息标记tag
            //第二个参数,false非批量应答
            channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
        };

        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("work1 消息消费被中断");
        };
        System.out.println("worker1等待1s接收消息.......");
        //设置手动应答
        channel.basicConsume(QUEUE_NAME, false, deliverCallback, cancelCallback);
    }

}
package com.xkj.org.mq.ack;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.xkj.org.utils.RabbitMQUtil;

import java.io.IOException;

public class Worker02 {

    private static final String QUEUE_NAME = "ack_queue";

    public static void main(String[] args) throws IOException {
        Channel channel = RabbitMQUtil.getChannel();
        //预期值5
        channel.basicQos(5);
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("接受到消息:"+ new String(message.getBody(), "UTF-8"));
            //第一个参数,消息标记tag
            //第二个参数,false非批量应答
            channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
        };

        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("work2 消息消费被中断");
        };
        System.out.println("worker2等待30s接收消息.......");
        //设置手动应答
        channel.basicConsume(QUEUE_NAME, false, deliverCallback, cancelCallback);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷土重来…

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值