【发布时间】:2017-01-24 03:17:26
【问题描述】:
引用本书,RabbitMQ in Depth:
一个 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 指示失败的请求。然后由出版商决定 决定如何处理消息。
更改上面的示例,我只将消息的路由键更改为不应在任何地方路由的内容(没有与路由键匹配的绑定),从日志中我可以看到 only 关注。
From handling confirmation on publisher side undefined
现在我更困惑了,究竟是什么发布者在这里得到通知?我会理解它收到一个错误,例如Can't route anywhere,这将与上面的报价保持一致。但是正如您所看到的,err 没有定义,并且作为附带问题,即使他们的官方文档中的amqplib 使用的是(err, ok),在任何情况下我都没有看到这些定义。所以这里的输出和上面的例子一样,上面的例子和不可路由的消息有什么不同。
那么我在这里做什么,何时确切地通知发布者关于消息发生了什么?任何使用 PublisherConfirms 的具体示例?从上面的日志中,我得出的结论是,如果您希望 100% 确定该消息已入队,那么使用它是很好的。
【问题讨论】: