检索从中消费消息的 RabbitMQ 队列的名称
Posted
技术标签:
【中文标题】检索从中消费消息的 RabbitMQ 队列的名称【英文标题】:Retrieve name of RabbitMQ Queue where message was consumed from 【发布时间】:2014-03-26 08:54:18 【问题描述】:使用附加到多个队列并配置有ChannelAwareMessageListener
的SimpleMessageListenerContainer
。是否可以确定从哪个队列消费了一条消息?特别是如果消息是从 Exchange 路由到队列的。
如果消息直接发送到队列,MessageProperties#getReceivedRoutingKey
将包含队列名称,但如果消息通过 Exchange 路由到队列,则此信息包含使用的路由键。
我正在寻找一种机制,无论消息如何传递到队列,都可以正确提取此信息。或者在 RabbitMQ 端使用包含此信息的标头来丰富信息的机制。
【问题讨论】:
当消息直接发送到队列时,它们实际上是发送到直接交换器。此直接交换将路由键解释为它必须将消息转发到的队列名称。这就是在这种情况下路由键与队列名称相同的原因。 消息不包含任何信息,它们被路由到哪里(我认为这是合理的)。在这种情况下,我认为消费者是负责知道它从哪个队列接收消息的人。您能否添加有关您的方案的更多信息,例如为什么需要知道队列名称?也许另一种消息传递模式更适合。 消息确实包含接收到的交换(或者它可以由 Spring AMQP 实现确定,不确定是哪个),所以有一些路由信息。我只是想获得有关它可能来自哪个队列的相同信息。我有一个消费者附加到多个队列,我无法确定消息来自哪个队列。我可以将我的消费者附加到一个队列,然后我可以确定队列。似乎每个到队列的连接都被赋予了一个 consumer_tag 并且应该可以确定队列但它没有被暴露。 【参考方案1】:我有一个类似的问题,我想将队列名称添加到 slf4j MDC 上下文中。
我找到的唯一解决方案是继承 SimpleMessageListenerContainer
并为队列名称或在我的情况下为 MDC 上下文(基本上是线程本地)设置一个 ThreadLocal 变量。
因为SimpleMessageListenerContainer
仍然不知道究竟是哪个队列(您可以将多个队列绑定到一个容器),所以每个容器只允许一个队列,我认为无论如何都应该这样做。
在我公司自己的代码库中,我们有一个神奇的SimpleMessageListenerContainerFactory
,它基于路由注释创建自定义SimpleMessageListenerContainer
(想想用于amqp 的spring mvc @RequestMapping
)。如果有兴趣,也许我们可以加快开源。
【讨论】:
这也是我们最终所做的。以上是关于检索从中消费消息的 RabbitMQ 队列的名称的主要内容,如果未能解决你的问题,请参考以下文章