引用《 RabbitMQ》一书的内容:
当消费者应用程序直接将其已发布的消息直接发送到发布者的所有队列上,或者该消息已排队并在请求时持久存在时,便将Basic.Ack请求发送给发布者。
与混淆Has been directly consumed
,是否意味着当消费者发送ack
给代理发布者时将被告知消费者处理消息成功?还是意味着当消费者刚刚从队列中收到消息时,发布者将得到通知?
or that the message was enqueued and persisted if requested
。这是像变种一样,还是会在发生任何一种情况时通知发布者?(在这种情况下,发布商将收到两次通知)
使用node.js
并amqplib
想检查实际发生了什么:
// consumer.js amqp.connect(...) .then(connection => connection.createChannel()) .then(() => { assert exchange here }) .then(() => { assert queue here }) .then(() => { bind queue and exchange here }) .then(() => { channel.consume(QUEUE, (message) => { console.log('Raw RabbitMQ message received', message) // Simulate some job to do setTimeout(() => { channel.ack(message, false) }, 5000}) }, { noAck: false }) }) // publisher.js amqp.connect(...) .then(connection => connection.createConfirmChannel()) .then(() => { assert exchange here }) .then(() => { channel.publish(exchange, routingKey, new Buffer(...),{}, (err, ok) => { if (err) { console.log('Error from handling confirmation on publisher side', err) } else { console.log('From handling confirmation on publisher side', ok) } }) })
运行示例,我可以看到以下日志:
From handling confirmation on publisher side undefined Raw RabbitMQ message received Time to ack the message
据我所知,至少在此日志中,仅在消息入队时才会通知发布者?(因此,让消费者ack
阅读消息不会以任何方式影响发布者)
进一步报价:
如果无法路由消息,则代理将发送指示失败的Basic.Nack RPC请求。然后由发布者决定如何处理消息。
更改上面的例子,在这里我不仅改变了信息的路由关键的东西,不应该被路由的任何地方(没有绑定,将匹配路由键),从日志中我可以看到只有以下。
From handling confirmation on publisher side undefined
现在我更加困惑,确切地在这里通知了哪些发布商?我会理解它会收到一个错误,例如Can't route anywhere
,该错误将与上面的引用对齐。但是,正如您所看到的err
,即使amqplib
在他们的官方文档中使用(err, ok)
,也没有定义和附带问题,在任何情况下,我都看不到这些定义。因此,这里的输出与上面的示例相同,上面的示例与不可路由的消息之间可能会有何不同。
那么到现在为止,什么时候确切地将有关消息发生的情况通知发布者?有什么具体示例可以使用PublisherConfirms?从上面的日志记录中,我得出的结论是,在您希望100%确定消息已入队的情况下,拥有它是很好的。