Java RabbitMQ:如何指定要发布到的队列?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18531308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 08:49:13  来源:igfitidea点击:

RabbitMQ: How to specify the queue to publish to?

javarabbitmqmessagingpublish-subscribechannel

提问by

RabbitMQ's Channel#basicConsumemethod gives us the following arguments:

RabbitMQ 的Channel#basicConsume方法为我们提供了以下参数:

channel.basicConsume(queueName, autoAck, consumerTag, noLocal,
    exclusive, arguments, callback);

Giving us the ability to tell RabbitMQ exactly which queue we want to consume from.

使我们能够准确地告诉 RabbitMQ 我们要从哪个队列中消费。

But Channel#basicPublishhas no such equivalency:

Channel#basicPublish没有这样的等价:

channel.basicPublish(exchangeName, routingKey, mandatory, immediateFlag,
    basicProperties, messageAsBytes);

Why can't I specify the queue to publish to here?!? How do I get a Channelpublishing to, say, a queue named logging?Thanks in advance!

为什么我不能在这里指定要发布到的队列?!?我如何Channel发布到一个名为 的队列logging提前致谢!

采纳答案by Vishal John

Basically queues can be binded to an exchange based on routingKeys.

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

Assume that you have 3 different publishers.
Publisher1 sending message to exchange with routingKey "events"
Publisher2 sending message to exchange with routingKey "tasks"
Publisher3 sending message to exchange with routingKey "jobs"

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

You can have a consumer that consumes only messages with specific routhingKey.
For example in order to have a consumer for "events" messages you declare like this

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

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

If you want to consume all the messages coming to the exchange you give the routing as '#'

如果您想使用所有进入交换的消息,您可以将路由指定为“#”

So in short what i can say is,
1. Messages will be published to an exchange.
2. Queues will be bound to exchange based on routingKeys.
3. RabbitMQ will forward messages with matching routing keys to the corresponding queues.

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

Please see the tutorial - http://www.rabbitmq.com/tutorials/tutorial-three-java.html

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

The core idea in the messaging model in RabbitMQ is that the producer never sends any messages directly to a queue. Actually, quite often the producer doesn't even know if a message will be delivered to any queue at all. Instead, the producer can only send messages to an exchange

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

回答by Tien Nguyen

please try this:

请试试这个:

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

It worked for my project.

它适用于我的项目。

回答by Brian Reischl

To expand on @Tien Nguyen's answer, there is a "cheat" in RabbitMQ that effectively lets you publish directly to a queue. Each queue is automatically bound to the AMQP default exchange, with the queue's name as the routing key. The default exchange is also known as the "nameless exchange" - ie its name is the empty string. So if you publish to the exchange named ""with routing key equal to your queue's name, the message will go to just that queue. It is going through an exchange as @John said, it's just not one that you need to declare or bind yourself.

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

I don't have the Java client handy to try this code, but it should work.

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

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

That said, this is mostly contrary to the spirit of how RabbitMQ works. For normal application flow you should declare and bind exchanges. But for exceptional cases the "cheat" can be useful. For example, I believe this is how the Rabbit Admin Console allows you to manually publish messages to a queue without all the ceremony of creating and binding exchanges.

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