春季兔子每个主题的并发消费者

时间:2015-04-07 00:55:23

标签: java spring rabbitmq

可以使spring-rabbit支持单个主题的多个并发消费者吗?

以下是详细信息

我的系统使用手动ack模式,通过spring-rabbit进行主题交换(Spring 4.0.6)。模式如下:

  • 消息进入ChannelAwareMessageListener
  • 工厂方法生成适当的工作程序并传入对通道的引用
  • 如果工作人员成功处理了该消息,则消息为Ack'
  • 如果工作人员不成功或发生异常,则该消息为Nack&d并发送到死信队列以供以后处理

由于其中一些工作人员可能需要花费大量时间来完成IO绑定处理,因此我需要能够设置更多的并发使用者。

经过一些测试后,我发现有时消费者会收到相同的消息。果然,看一下文档(http://docs.spring.io/spring-framework/docs/4.0.6.RELEASE/javadoc-api/org/springframework/jms/listener/DefaultMessageListenerContainer.html#setConcurrentConsumers-int-),证实了我的发现:

  

除非特定于供应商的设置措施明确允许,否则不要增加主题的并发使用者数量。通过常规设置,这将导致同时消耗相同的消息,这几乎是不可取的。

我的问题如下:

  1. 哎呀"除非供应商特定的设置措施明确允许它"意思?是否有补丁/版本/配置或Rabbit支持此功能?
  2. 我可以轻松地在客户端上编写代码,以防止在其他工作人员处理过消息时处理该消息。那么,我对这条消息做了什么呢?发送nack?忽略它?如果我nack然后实际处理消息的工作人员在一段时间之后发送ack会发生什么?会抛出异常吗?
  3. 提前致谢...

1 个答案:

答案 0 :(得分:1)

你提到的警告是关于JMS而不是RabbitMQ。看看Spring RabbitMQ documentation。该文档不包含此警告。

一旦消息被传递到队列(无论交换类型如何),消费者/工人一次只能(假设没有问题)。

如果您收到两次相同的消息,则存在某个问题:

  • 消息被解雇并重新排队
  • 通道/连接在客户端关闭
  • 存在网络问题,Rabbit会自动重新排队消息(服务器端和客户端关闭通道/连接)

对于最后两点,您应该收到一些错误消息。

请注意,这一点在我看来是不必要的,可以解释这个问题:

  
      
  • 工厂方法生成适当的工作人员并传入   参考频道
  •   

SimpleMessageListenerContainer已使用Executor。当您使用自己的执行程序时,spring-amqp通道池(如果您使用任何通道)和执行程序之间可能存在问题,例如。因为spring-amqp相信它不再被使用,所以该频道已关闭。

不是生成自己的线程,而是在当前ChannelAwareMessageListener#onMessage线程的同一个线程上处理消息。