java - 如何使用 SimpleMessageListenerContainer 禁用 RabbitMQ 预取计数

标签 java spring rabbitmq spring-amqp spring-rabbit

RabbitMQ 提供了选择性设置预取计数的功能。

使用 spring-amqp 的 SimpleMessageListenerContainer,我注意到预取计数始终被设置。我无法将预取计数设置为 0,因为 SimpleMessageListenerContainer 将其设置为至少 txSize,该值必须大于零(即使不涉及任何事务)。那么有没有办法禁用预取计数,即使其不受限制?

以下是 spring-amqp 的相关代码:

SimpleMessageListenerContainer.createBlockingQueueConsumer() 执行以下操作:

    int actualPrefetchCount = prefetchCount > txSize ? prefetchCount : txSize;

BlockingQueueConsumer.start() 执行以下操作:

    if (!acknowledgeMode.isAutoAck()) {
        // Set basicQos before calling basicConsume (otherwise if we are not acking the broker
        // will send blocks of 100 messages)
        try {
            channel.basicQos(prefetchCount);
        }

总是在 Springs 的 BlockingQueueConsumer 中调用 basicQos() 的原因是什么?没有禁用预取计数的用例吗? (显然自动确认除外)。

The rabbitmq documentation讨论使用 channel (全局)范围设置预取计数的开销。没有明确提及与根本不设置相比,使用消费者范围设置它是否有任何开销。如果我没记错的话,spring 总是将其设置为消费者范围。它真的没有任何开销吗?不过,没有不设置它的选项似乎很奇怪。

谢谢

最佳答案

由于当前的实现将交给内部队列,由于早期的rabbitmq客户端的工作方式,如果消费者跟不上,不设置qos将导致OOM情况。

事实上,在 Spring AMQP 的早期版本中,自动确认会发生这种情况,因此队列根据预取大小进行限制,以阻止代理在这种情况下发送消息。

在2.0中,我们是planning a new container implementation that avoids this queue因为兔子客户端不再有需要它的问题。那么我们可以考虑支持qos=0。

关于java - 如何使用 SimpleMessageListenerContainer 禁用 RabbitMQ 预取计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37764309/

相关文章:

erlang - 在 Windows 10 64 位上安装 Erlang/RabbitMQ

java - 如何在 Java 中正确构造 JSON 响应

java - 如何从命令行运行具有多个包的 Selenium testNG 文件?

java.sql.SQLException : ORA-01017: invalid username/password; logon denied 异常

java - Spring bean注入(inject)没有显式的依赖声明?

java - Spring和Rabbit mq消息顺序

java - 数据报 channel 套接字不编写 Java

Java:new、inheritance和objects number

Spring 3 EJB 3.1 JPA 2

c# - RabbitMQ:将消息从一台电脑发送到另一台电脑