Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java RabbitMQ:如何指定要发布到的队列?_Java_Rabbitmq_Messaging_Publish Subscribe_Channel - Fatal编程技术网

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

Java RabbitMQ:如何指定要发布到的队列?,java,rabbitmq,messaging,publish-subscribe,channel,Java,Rabbitmq,Messaging,Publish Subscribe,Channel,RabbitMQ的Channel#basicConsume方法为我们提供了以下参数: channel.basicConsume(queueName, autoAck, consumerTag, noLocal, exclusive, arguments, callback); 使我们能够准确地告诉RabbitMQ要从哪个队列消费 但是Channel#basicPublish没有这样的等价性: channel.basicPublish(exchangeName, routingKey,

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

channel.basicConsume(queueName, autoAck, consumerTag, noLocal,
    exclusive, arguments, callback);
使我们能够准确地告诉RabbitMQ要从哪个队列消费

但是
Channel#basicPublish
没有这样的等价性:

channel.basicPublish(exchangeName, routingKey, mandatory, immediateFlag,
    basicProperties, messageAsBytes);
为什么我不能在这里指定要发布到的队列如何获得
频道
发布到(比如)名为
日志记录的队列?提前感谢

请尝试以下操作:

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

它对我的项目起到了作用。

基本上,队列可以基于路由键绑定到exchange

假设您有3个不同的发布者。
发布者1使用routingKey“事件”向exchange发送消息
发布者2使用routingKey“任务”向exchange发送消息
发布者3使用routingKey“作业”向exchange发送消息

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

 channel.queueBind(queueName, exchangeName, "events");
如果要使用所有发送到exchange的邮件,请将路由设置为“#”

所以简而言之,我能说的是,
1.消息将发布到exchange。
2.队列将根据路由密钥绑定到exchange。
3.RabbitMQ将具有匹配路由密钥的消息转发到相应的队列

请参阅教程-


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

要扩展@Tien Nguyen的回答,RabbitMQ中有一个“欺骗”,可以让您直接发布到队列。每个队列自动绑定到AMQP默认交换,队列名称作为路由密钥。默认交换也称为“无名交换”——即其名称为空字符串。因此,如果您使用与队列名称相同的路由密钥发布到名为“
的exchange,则消息将只发送到该队列。正如@John所说,这是一种交换,你不需要声明或约束自己

我手头没有Java客户端来尝试这段代码,但它应该可以工作

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

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

您可以使用独占队列、直接交换和已知队列名称以及特定的路由密钥+主题交换来完成所需操作。感谢@zaq178miami(+1)-您可以提供一个代码示例吗?感谢@tien nguyen(+1)-但是,看起来您使用的是超负荷的
basicPublish
。在该重载中,第二个参数(作为“yourQueueName”使用)称为“routingKey”。因此,“routingKey”是“queue name”的RabbitMQ行话?@TicketMonster routingKey并不意味着队列。队列将绑定到基于routingKey的交换机,并且只接收具有该routingKey的消息。请参阅我的答案。更详细地说,该消息将发送到默认交换机,因此路由key实际上将发送到队列。但不,它们不是等价的@John(+1和绿色复选框)-感谢您提供的有用、全面和信息丰富的答案!即使队列也绑定到一个exchange,这种欺骗也会起作用吗?是的,它会起作用,我们有代码可以对绑定到其他exchange的队列执行此操作。太棒了。这正是我自动测试所需的。谢谢您这在中测试之外的许多其他场景中也很方便包括本地工作队列和消息的“恢复”等。