我正在向没有任何绑定任何队列的主题交换发送消息。只是一个空白的交流。 通道创建为确认通道,每次发送消息时都会调用确认回调。 奇怪的是,对于每条消息,我都得到了答案。RabbitMQ:通过交换没有任何现有绑定的消息确认
我做错了什么或错误地理解发布者确认的工作方式? 如何知道消息是否被路由到队列或被交换机丢弃?
我使用amqplib作为节点。
我正在向没有任何绑定任何队列的主题交换发送消息。只是一个空白的交流。 通道创建为确认通道,每次发送消息时都会调用确认回调。 奇怪的是,对于每条消息,我都得到了答案。RabbitMQ:通过交换没有任何现有绑定的消息确认
我做错了什么或错误地理解发布者确认的工作方式? 如何知道消息是否被路由到队列或被交换机丢弃?
我使用amqplib作为节点。
它是由设计。检查这个link。它说得很清楚:
什么时候会确认消息?
对于不可路由的消息,经纪人 会发出一次确认交换验证的消息不会路由 向任何队列(返回队列列表为空)。如果该消息也是 发布为强制性的,则basic.return会在 basic.ack之前发送给客户端。对于否定确认 (basic.nack)也是如此。
对于可路由消息,当消息被所有队列接受时,发送basic.ack。对于路由到持久的 队列的持久性消息,这意味着持久化到磁盘。对于镜像队列,这意味着 所有镜像都接受了该消息。
好吧,大概我没有解释清楚我的问题。因此,这里是一些代码:
var amqp = require('amqplib/callback_api');
amqp.connect('amqp://host' , function(err, conn) {
conn.createConfirmChannel(function(err, ch) {
channel.assertExchange('my_awsome_exchange', 'topic', {durable: true});
channel.publish('my_awsome_exchange', 'routing_key', new Buffer('some data'),
{
mandatory: true
},
function(err){
// err is null no matter if a queue is bound to the exchange or not
console.log(err);
});
});
});
正如你可以看到创建了一个交流,但没有队列绑定到这个交流呢。所以我的期望是发送消息给这个交换机永远不会被收回。 @Teddy:我从文档中知道这一部分,这就是为什么我很困惑的原因。由于该消息未被路由到任何队列,因此我预计该消息将被删除。
确认频道的行为即使在发布到无约束力的交易所时,发行商仍处于阻止模式,它必须等待来自代理的'确认'。如果如你所说,它的设计目的不是在这种情况下,出版商将永远等待,这听起来不正确,对吗? –
好吧,我明白你的意思,你的意思是你认为它应该发回拒绝? –
我的感觉仍然回复更有意义。即使你的交换有一些绑定,但是如果你的excahnge类型是直接或主题,仍然有消息不会被路由到任何队列的情况,因为这些绑定密钥都不匹配你的路由密钥。交换队列的路由逻辑对发布者应该是透明的。 –
是否有可能共享示例代码?核实。可能是你使用'$ queue-> ack($ message ['delivery_tag']);' –
什么是“空白交换”?你在谈论无名的交换吗?或者默认的“amqp.topic”交换还是什么?这里有很多不一致的地方......如果回调被设置为收到消息时被调用,那么显然必须有一些带有某种绑定的队列。如果你使用的是无名交换,那么这是直接交换而非话题! – cantSleepNow