首页 文章

Spring AMPQ多个消费者与更高的预取值

提问于
浏览
2

即使在阅读了大量SO问题(12)和文章之后,还不清楚哪个是为消费者设置的更好选择 . 多个消费者或更高的预取值?

根据我的理解,当涉及到 SimpleRabbitListenerContainerFactory 时,因为它最初设计为每个连接只有一个线程,它被设计用于解决amqp-client每个连接只有一个线程的限制,这是否意味着设置多个消费者赢了因为只有一个线程实际上是从兔子消费而不是把它交给多个消费者(线程),所以会产生很大的不同?或者实际上有几个消费者在同一时间消费?

那么关于预取/消费者的兔子 Spring 季实施的最佳实践是什么?应该何时使用另一个?我应该切换到这个新的 DirectRabbitListenerContainerFactory 吗?它是'better'还是只取决于用例?

在高预取时我看到的一些缺点是,如果应用程序消耗了更多可以保存在缓冲区中的消息,它可能会导致内存问题? (还没有实际测试过这个,tbh)

当涉及到多个消费者时,我看到在操作系统级别上打开更多文件描述符的缺点,我看到有关每个消费者实际为每个ack ping兔子的文章,这使得它变得更慢 .

仅供参考,如果它是相关的,我通常将我的配置设置如下:

@Bean
public ConnectionFactory connectionFactory() {
final CachingConnectionFactory connectionFactory = new CachingConnectionFactory(server);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setRequestedHeartBeat(requestedHeartBeat);
return connectionFactory;
}

@Bean
public AmqpAdmin amqpAdmin() {
    AmqpAdmin admin = new RabbitAdmin(connectionFactory());
    admin.declareQueue(getRabbitQueue());
    return admin;
}

@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
final SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setConcurrentConsumers(concurrency);
factory.setMaxConcurrentConsumers(maxConcurrency);
factory.setPrefetchCount(prefetch);
factory.setMissingQueuesFatal(false);
return factory;
}

@Bean
public Queue getRabbitQueue() {
final Map<String, Object> p = new HashMap<String, Object>();
p.put("x-max-priority", 10);
return new Queue(queueName, true, false, false, p);
}

1 回答

  • 0

    没有; SMLC不是“为每个连接设计一个线程”,它旨在解决amqp-client每个连接只有一个线程的限制,以便线程通过内存队列切换到消费者线程;这已不再是这种情况 . 客户端是多线程的,每个消费者有一个专用线程 .

    拥有多个消费者(增加并发性)是完全有效的(即使对于较旧的客户端也是如此) .

    预取实际上是为了减少网络抖动并提高整体吞吐量 . 是否需要增加并发性实际上与预取正交 . 如果(a)您的侦听器处理每条消息的速度相对较慢,并且(b)严格的消息排序并不重要,则通常会增加并发性 .

    引入了 DirectListenerContainer 以提供不同的线程模型,其中直接在amqp-client线程上调用侦听器 .

    Choosing a Container中描述了选择一个容器而不是另一个容器的原因 .

    SMLC提供以下功能,但不提供DMLC:txSize - 使用SMLC,您可以将其设置为控制事务中传递的消息数量和/或减少确认数量,但可能会导致失败后重复交付的数量增加 . (DMLC确实有mesagesPerAck,它可用于减少ack,与txSize和SMLC相同,但它不能用于事务 - 每个消息在单独的事务中传递和确认) . maxConcurrentConsumers和消费者缩放间隔/触发器 - DMLC中没有自动缩放功能;但是,它允许您以编程方式更改consumersPerQueue属性,并相应地调整使用者 . 但是,DMLC与SMLC相比具有以下优点:在运行时添加和删除队列更有效;使用SMLC,重新启动整个消费者线程(所有消费者都被取消并重新创建);使用DMLC,未受影响的消费者不会被取消 . 避免RabbitMQ客户端线程和使用者线程之间的上下文切换 . 线程在消费者之间共享,而不是为SMLC中的每个消费者提供专用线程 . 但是,请参阅“线程和异步使用者”一节中有关连接工厂配置的重要说明 .

相关问题