RabbitMQ:如何指定要发布到的队列?
Posted
技术标签:
【中文标题】RabbitMQ:如何指定要发布到的队列?【英文标题】:RabbitMQ: How to specify the queue to publish to? 【发布时间】:2013-09-03 02:07:59 【问题描述】:RabbitMQ 的Channel#basicConsume
方法为我们提供了以下参数:
channel.basicConsume(queueName, autoAck, consumerTag, noLocal,
exclusive, arguments, callback);
让我们能够准确地告诉 RabbitMQ 我们想从哪个队列消费。
但是Channel#basicPublish
没有这样的等价物:
channel.basicPublish(exchangeName, routingKey, mandatory, immediateFlag,
basicProperties, messageAsBytes);
为什么我不能在这里指定要发布到的队列?!? 如何将Channel
发布到例如名为logging
的队列?提前致谢!
【问题讨论】:
你想做的事情可以通过独占队列、直接交换和已知队列名称以及特定的路由键+主题交换来完成。 【参考方案1】:为了扩展@Tien Nguyen 的答案,RabbitMQ 中有一个“作弊”,可以有效地让您直接发布到队列。每个队列都自动绑定到 AMQP 默认交换器,队列的名称作为路由键。默认交换也称为“无名交换”——即它的名称是空字符串。因此,如果您使用与队列名称相同的路由键发布到名为""
的交换器,则消息将仅发送到该队列。正如@John 所说,它正在通过交换,这不是您需要声明或约束自己的交换。
我没有方便的 Java 客户端来尝试此代码,但它应该可以工作。
channel.basicPublish("", myQueueName, false, false, null, myMessageAsBytes);
也就是说,这与 RabbitMQ 的工作原理大相径庭。对于正常的应用程序流程,您应该声明和绑定交换。但对于特殊情况,“作弊”可能很有用。例如,我相信这就是 Rabbit 管理控制台允许您手动将消息发布到队列的方式,而无需创建和绑定交换的所有仪式。
【讨论】:
即使队列也绑定到交易所,这种作弊是否有效? 是的,它会的,我们有代码可以对绑定到其他交换的队列执行此操作。 太棒了。正是我需要的自动化测试。谢谢 这在测试之外的许多其他场景中也很方便,包括本地工作队列和消息的“恢复”等。【参考方案2】:基本上,队列可以绑定到基于 routingKeys 的交换。
假设您有 3 个不同的发布商。 Publisher1 发送消息以与 routingKey“事件”进行交换 Publisher2 发送消息以与 routingKey“任务”进行交换 Publisher3 发送消息以与 routingKey “jobs”进行交换
您可以让消费者只使用具有特定 routhingKey 的消息。 例如,为了让您声明这样的“事件”消息的消费者
channel.queueBind(queueName, exchangeName, "events");
如果你想消耗所有进入交换的消息,你将路由指定为'#'
简而言之,我能说的是, 1. 消息将发布到交易所。 2.队列会根据routingKeys绑定交换。 3. RabbitMQ 会将路由键匹配的消息转发到对应的队列中。
请看教程-http://www.rabbitmq.com/tutorials/tutorial-three-java.html
RabbitMQ 中消息传递模型的核心思想是生产者永远不会将任何消息直接发送到队列。实际上,生产者通常根本不知道消息是否会被传递到任何队列。相反,生产者只能向交换器发送消息
【讨论】:
真棒@John(+1 和绿色检查) - 感谢有用,彻底和信息丰富的答案!【参考方案3】:请试试这个:
channel.basicPublish("", yourQueueName, null,
message.getBytes((Charset.forName("UTF-8"))));
它适用于我的项目。
【讨论】:
感谢 @tien nguyen (+1) - 但是,您似乎正在使用basicPublish(java.lang.String exchange, java.lang.String routingKey, AMQP.BasicProperties props, byte[] body)
重载 basicPublish
。在该重载中,第二个参数(您拥有的“yourQueueName”称为“routingKey”。那么,“routingKey”是“队列名称”的 RabbitMQ 术语吗?
@TicketMonster routingKey 不代表队列。队列将绑定到基于 routingKey 的交换,并且只会接收具有该 routingKey 的消息。看我的回答。
更详细地说,消息被发送到默认交换器,因此路由键实际上将发送到队列。但不,它们不等价以上是关于RabbitMQ:如何指定要发布到的队列?的主要内容,如果未能解决你的问题,请参考以下文章