RabbitMq:不公平分发和预取值

不公平分发:在消费者work01中,睡眠时间较短,处理消息速度很快。相反,再消费者work02中睡眠时间较长,处理速度较慢。从而导致有的消费者一直处于空闲状态。这是一种不太好的额处理方式

如何实现:消费者中设置参数channel.bascicQos(1)。信道中只允许传输一条消息,那么当这条消息处理完后,队列会立马发送下一条消息,所以这个时候快的不断处理,慢的等待当前处理完在处理下一条,这样就实现了能者多劳(所以我们给效率慢的那个消费者获取消息的信道设置,快的不用设置,不要设置错了)

public class Producer {
    public static final String QUEUE_NAME = "test_basic_qos";

    public static final String EXCHANGE_NAME = "test_basic_qos";

    public static void main(String[] args) throws IOException, TimeoutException {
        Channel channel = RabbitMqUtils.getChannel();
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"basic.qos");
        Scanner scanner = new Scanner(System.in);
        while(scanner.hasNext()) {
            String message = scanner.next();
            System.out.println("发送消息为:" + message);
            channel.basicPublish(EXCHANGE_NAME,"basic.qos",null,message.getBytes(StandardCharsets.UTF_8));
        }
    }
}
public class Consumer02 {
    public static final String QUEUE_NAME = "test_basic_qos";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            try {
                SleepUtils.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("高性能服务器接受:" + new String(message.getBody()));
            channel.basicAck(message.getEnvelope().getDeliveryTag(),false);
        };
        CancelCallback cancelCallback = consumerTag -> {};
        channel.basicConsume(QUEUE_NAME,false,deliverCallback,cancelCallback);
    }
}
public class Consumer01 {

    public static final String QUEUE_NAME = "test_basic_qos";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        channel.basicQos(1);
        DeliverCallback deliverCallback = (consumerTag,message) -> {
            try {
                SleepUtils.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("低性能服务器接受:" + new String(message.getBody()));
            channel.basicAck(message.getEnvelope().getDeliveryTag(),true);
        };
        CancelCallback cancelCallback = consumerTag -> {};
        channel.basicConsume(QUEUE_NAME,false,deliverCallback,cancelCallback);
    }
}

 

 

 

 

预取值(perfetch) :用于定义通道上允许的未确认消息的最大数量。一旦数量达到配置的数量,RabbitMQ将停止在通道上传递更多消息,除非至少有一个未处理的消息被确认。

举例:假设在通道上有未确认的消息5,6,7,8,并且通道的预取计数为4,此时RabbtMQ将不会在该通道上再传递任何消息,除非至少有一个为应答的消息被ack。比如说tag=6这个消息刚刚被确认ack,RabbitMQ将会感知这个情况并再发一条消息,消息应答和Qos预取值对用户吞吐量有重大影响。通常,增加预取值将提高向消费者传递消息的速度,

虽然自动应答传输消息速率是最佳的,但是,在这种情况下已传递但尚未处理 的消息的数量也会增加,从而增加了消费者的 RAM 消耗 ( 随机存取存储器 ) 应该小心使用具有无限预处理
的自动确认模式或手动确认模式,消费者消费了大量的消息如果没有确认的话,会导致消费者连接节点的
内存消耗变大,所以找到合适的预取值是一个反复试验的过程,
perfetchCount设置为0,轮询分发,设置为1,则不公平分发,设置大于1,则是预取值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值