简体   繁体   English

兔子 mq 预取不明白

[英]Rabbit mq prefetch undestanding

I understand below我在下面理解

prefetch simply controls how many messsages the broker allows to be outstanding at the consumer at a time.预取只是控制代理允许在消费者一次未处理的消息数量。 When set to 1, this means the broker will send 1 message, wait for the ack, then send the next.当设置为 1 时,这意味着代理将发送 1 条消息,等待确认,然后发送下一条。

but questions regarding following scenarios:但有关以下情况的问题:

  1. Lets say prefetch is 200, we have 2 consumers idle.假设预取为 200,我们有 2 个消费者空闲。 Broker got 150 messages, I think broker will pick one random and will send all 150 messages?经纪人收到了 150 条消息,我认为经纪人会随机选择一条并发送所有 150 条消息? I think yes it wont do sharing between consumers.我认为是的,它不会在消费者之间进行共享。

  2. Lets say one consumer is having 100 messages in unack and one is idle and prefetch again is 200. Now we got 50 more messages, again I think broker will give those 50 to either one randomly?假设一个消费者在 unack 中有 100 条消息,一个处于空闲状态,并且再次预取为 200 条。现在我们又收到了 50 条消息,我认为代理会随机将这 50 条消息分配给其中一个吗? Or it will not give to consumer who already have 100 messages that not acked yet或者它不会给已经有 100 条尚未确认的消息的消费者

  3. If prefetch is 200, one consumer got 200, will listener block that thread (spring rabbitmq listner method) to send ack until all 200 processed?如果预取为 200,一个消费者得到 200,监听器会阻塞该线程(spring rabbitmq 监听器方法)发送 ack 直到所有 200 个处理完毕? I think it will not send ack one by one and will wait until all prefetched messages processed.我认为它不会一一发送ack,会等到处理完所有预取的消息。 In other words if prefetch is 200 and if broker delivers 200 messages, when broker will start getting ack?换句话说,如果 prefetch 是 200 并且如果 broker 传递了 200 条消息,那么 broker 什么时候开始得到 ack?

If there are two active consumers, the broker will distribute new messages fairly (until each instance has 200 outstanding).如果有两个活跃的消费者,代理将公平地分发新消息(直到每个实例有 200 个未完成的消息)。

If there are 150 messages in the queue and no consumers running;如果队列中有 150 条消息并且没有消费者在运行; the first consumer to start will (likely) get all 150, but when both are running, the distribution is fair.第一个开始的消费者将(可能)获得全部 150 个,但是当两者都运行时,分配是公平的。

If there are 200 outstanding at each consumer, the broker will send new messages on demand as each one is ack'd.如果每个消费者有 200 条未完成的消息,代理将在每个消息都被确认时按需发送新消息。 The consumer thread is not "blocked", it is just that the broker will send no more messages.消费者线程没有“阻塞”,只是代理不会再发送消息。

By default, spring will ack each message one-at-a-time.默认情况下,spring 将一次确认每条消息。 This behavior can be changed by setting the container's batchSize property.可以通过设置容器的batchSize属性来更改此行为。 eg if it is set to 100, it will send an ack every 100 records;例如,如果设置为 100,它将每 100 条记录发送一个 ack; this improves performance, but adds the risk of duplicate deliveries after a failure.这提高了性能,但增加了失败后重复交付的风险。 In this case, the broker will send up to 100 new messages after the ack.在这种情况下,代理将在 ack 之后发送最多 100 条新消息。

In older versions, batchSize was called txSize .在旧版本中, batchSize被称为txSize

EDIT编辑

See this for an example;看这个例子; the default prefetch is 250 in recent versions.在最近的版本中,默认预取是 250。

@SpringBootApplication
public class So65201334Application {

    public static void main(String[] args) {
        SpringApplication.run(So65201334Application.class, args);
    }

    @RabbitListener(id = "foo", queues = "foo", autoStartup = "false")
    @RabbitListener(id = "bar", queues = "foo", autoStartup = "false")
    void listen(String in, @Header(AmqpHeaders.CONSUMER_TAG) String tag) throws InterruptedException {
        System.out.println(tag);
        Thread.sleep(240_000);
    }

    @Bean
    public ApplicationRunner runner(RabbitTemplate template, RabbitListenerEndpointRegistry registry) {
        return args -> {
            for (int i = 0; i < 200; i++) {
                template.convertAndSend("foo", "bar");
            }
            registry.getListenerContainer("foo").start();
            System.out.println("Hit Enter to start the second listener and send more records");
            System.in.read();
            registry.getListenerContainer("bar").start();
            Thread.sleep(2000);
            for (int i = 0; i < 200; i++) {
                template.convertAndSend("foo", "bar");
            }
        };
    }

}

As expected, all 200 went to the first consumer:正如预期的那样,所有 200 个都流向了第一个消费者:

在此处输入图像描述

When the second consumer is started, the records are sent to both consumers, not the one that has no backlog.当第二个消费者启动时,记录会发送给两个消费者,而不是没有积压的消费者。 With the distribution now looking like this:分布现在看起来像这样:

在此处输入图像描述

When I increase the prefetch to 400, you can see that the new messages go 50% to each consumer.当我将预取增加到 400 时,您可以看到新消息 go 50% 发给每个消费者。

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM