16

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提前致谢!

4

3 回答 3

33

为了扩展@Tien Nguyen 的答案,RabbitMQ 中有一个“作弊”,可以有效地让您直接发布到队列。每个队列都自动绑定到 AMQP 默认交换器,队列的名称作为路由键。默认交换也称为“无名交换”——即它的名称是空字符串。因此,如果您发布到使用""与队列名称相同的路由键命名的交换,则消息将仅发送到该队列。正如@John 所说,它正在经历一场交换,这不是你需要声明或约束自己的交换。

我没有方便的 Java 客户端来尝试此代码,但它应该可以工作。

channel.basicPublish("", myQueueName, false, false, null, myMessageAsBytes);

也就是说,这与 RabbitMQ 的工作原理大相径庭。对于正常的应用程序流程,您应该声明和绑定交换。但是对于特殊情况,“作弊”可能很有用。例如,我相信这就是 Rabbit 管理控制台允许您手动将消息发布到队列的方式,而无需创建和绑定交换的所有仪式。

于 2014-05-06T18:53:49.987 回答
18

基本上队列可以绑定到基于 routingKeys 的交换。

假设您有 3 个不同的发布者。
Publisher1 发送消息以与 routingKey “事件”
交换 Publisher2 发送消息以与 routingKey “tasks”
交换 Publisher3 发送消息以与 routingKey “jobs” 交换

您可以拥有一个仅使用具有特定 routhingKey 的消息的消费者。
例如,为了让您声明这样的“事件”消息的消费者

 channel.queueBind(queueName, exchangeName, "events");

如果你想消耗所有进入交换的消息,你将路由指定为“#”

所以简而言之,我能说的是,
1. 消息将被发布到交易所。
2. 队列会根据routingKeys绑定交换。
3. RabbitMQ 会将路由键匹配的消息转发到相应的队列中。

请参阅教程 - http://www.rabbitmq.com/tutorials/tutorial-three-java.html

RabbitMQ 中消息传递模型的核心思想是生产者从不直接向队列发送任何消息。实际上,生产者通常根本不知道消息是否会被传递到任何队列。相反,生产者只能向交换器发送消息

于 2013-08-30T14:11:31.600 回答
5

请试试这个:

channel.basicPublish("", yourQueueName, null,
        message.getBytes((Charset.forName("UTF-8"))));

它适用于我的项目。

于 2013-08-30T12:09:34.883 回答