如何验证发布者确认行为

huangapple go评论85阅读模式
英文:

How do I verify publisher acknowledge behavior

问题

我正在使用发布者确认编写一个Go程序,并且我想验证当消息可以被传递/无法传递给代理时的行为。

我正在从一个集成测试中进行此操作,该测试设置一个队列,并要求我的系统代码发送到该队列名称。验证发布者确认的行为没有问题,但我无法引发导致发布者拒绝的情况。

我尝试使用以下代码向一个不存在的队列发送消息:

connection, err := amqp.Dial("amqp://localhost")
if err != nil {
	panic(err)
}
defer connection.Close()
channel, err := connection.Channel()
if err != nil {
	panic(err)
}
err = channel.Confirm(false)
if err != nil {
	panic(err)
}
pubAck, pubNack := channel.NotifyConfirm(make(chan uint64, 1), make(chan uint64, 1))
fmt.Println("Publish to queue: ", queueName)
msg := amqp.Publishing{
	Body: []byte("Hello")}
err = channel.Publish("", queueName, true, true, msg)
if err != nil {
	panic(err)
}
select {
case <-pubAck:
	fmt.Println("Ack")
case <-pubNack:
	fmt.Println("NAck")
}

队列名称确实是一个不存在的队列,并且执行sudo rabbitmqctl list_queues显示队列列表为空。

但它仍然打印出"Ack"。

我已将mandatoryimmediate都设置为true。

当mandatory标志为true且没有绑定与路由键匹配的队列,或者当immediate标志为true且匹配队列上的消费者没有准备好接受传递时,发布可能无法传递。

我的发送到不存在队列的方法是否错误?是否有其他方法可以发送一条消息以引发发布者拒绝?

英文:

I am writing a go program with publisher confirms, and I want to verify the behavior when a message can be delivered/not be delivered to the broker.

I am doing this from an integration test that sets up a queue, and asks my system code to send to that queue name. Verifying the behavior for publisher ack is no problem, but I cannot provoke a situation that results in a publisher nack.

I try to send a message to a non-existing queue with the following piece of code:

connection, err := amqp.Dial(&quot;amqp://localhost&quot;)
if err != nil {
	panic(err)
}
defer connection.Close()
channel, err := connection.Channel()
if err != nil {
	panic(err)
}
err = channel.Confirm(false)
if err != nil {
	panic(err)
}
pubAck, pubNack := channel.NotifyConfirm(make(chan uint64, 1), make(chan uint64, 1))
fmt.Println(&quot;Publish to queue: &quot;, queueName)
msg := amqp.Publishing{
	Body: []byte(&quot;Hello&quot;)}
err = channel.Publish(&quot;&quot;, queueName, true, true, msg)
if err != nil {
	panic(err)
}
select {
case &lt;-pubAck:
	fmt.Println(&quot;Ack&quot;)
case &lt;-pubNack:
	fmt.Println(&quot;NAck&quot;)
}

The queue name is indeed a non existing queue, and executing sudo rabbitmqctl list_queues shows that the list of queues is empty.

But it still prints "Ack"

I have set both mandatory and immediate to true

> Publishings can be undeliverable when the mandatory flag is
> true and no queue is bound that matches the routing key, or when the
> immediate flag is true and no consumer on the matched queue is ready
> to accept the delivery

Is my approach for sending to a non-existing queue a wrong approach, and is there another way I can send a message that will provoke a publisher nack?

答案1

得分: 1

RabbitMQ只会在负责队列的Erlang进程发生内部错误时返回basic.nack

因此,basic.ack/basic.nack仅确认RabbitMQ代理是否接收到消息,而不是最终的消费者是否接收到消息。请参考此页面上“Negative Acknowledgement”部分的最后一句话。

英文:

RabbitMQ will only return a basic.nack if

> an internal error occurs in the Erlang process responsible for a queue.

So, the basic.ack/basic.nack is only confirming if the RabbitMQ broker received the message, not if a "final" consumer did. See the last sentence of "Negative Acknowledgement" on this page.

huangapple
  • 本文由 发表于 2015年3月6日 02:28:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/28885109.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定