duan89197 2017-04-18 10:49
浏览 193
已采纳

没有消费者,但是当我发布内容时,为什么会立即返回确认? (golang / RabbitMQ的)

Below is the publisher code that I use. It requires acks before the message is taken off the queue. It's suppose to print out that it receives an Ack or nack (at the bottom of the code) from a consumer. If you just run the publisher code below by itself (without running a consumer code at same time), it suppose to just hang, waiting for ack or nack but it doesn't, it prints out an ack as if a consumer had sent it. So I'm confused if I have any part of the code wrong.

For the base code I used code from rabbitmq's official tutorial: https://www.rabbitmq.com/tutorials/tutorial-one-go.html

For ack/nack part of the code I followed this: https://agocs.org/blog/2014/08/19/rabbitmq-best-practices-in-go/

package main

import (
    "log"
    "github.com/streadway/amqp"
)

func failOnError(err error, msg string) {
    if err != nil {
        log.Fatalf("%s: %s", msg, err)
    }
}

func main() {

    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    failOnError(err, "Failed to connect to RabbitMQ")
    defer conn.Close()

    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()

     ch.Confirm(false)

    ack, nack := ch.NotifyConfirm(make(chan uint64, 1), make(chan uint64, 1))

    q, err := ch.QueueDeclare(
        "hello", // name
        false,   // durable
        false,   // delete when unused
        false,   // exclusive
        false,   // no-wait
        nil,     // arguments
    )
    failOnError(err, "Failed to declare a queue")

    body := "hello"
    err = ch.Publish(
        "",     // exchange
        q.Name, // routing key
        true,  // mandatory
        false,  // immediate
        amqp.Publishing{
            ContentType: "text/plain",
            Body:        []byte(body),
        })
    log.Printf(" [x] Sent %s", body)
    failOnError(err, "Failed to publish a message")

    select {
      case tag := <-ack:
          log.Println("Acked ", tag)
      case tag := <-nack:
          log.Println("Nack alert! ", tag)
    }
}
  • 写回答

1条回答 默认 最新

  • douwei4370 2017-04-18 12:40
    关注

    You are confusing publisher confirm acks and nacks with consumer side acks and nacks.

    The documentation states:

    For unroutable messages, the broker will issue a confirm once the exchange verifies a message won't route to any queue (returns an empty list of queues). If the message is also published as mandatory, the basic.return is sent to the client before basic.ack. The same is true for negative acknowledgements (basic.nack).

    For routable messages, the basic.ack is sent when a message has been accepted by all the queues. For persistent messages routed to durable queues, this means persisting to disk. For mirrored queues, this means that all mirrors have accepted the message.

    So you are seeing the correct behaviour. RabbitMQ is confirming that the messages arrived at the queue.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 vmware exsi重置后的密码
  • ¥15 易盾点选的cb参数怎么解啊
  • ¥15 MATLAB运行显示错误,如何解决?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 UE5#if WITH_EDITOR导致打包的功能不可用
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?
  • ¥15 电磁场的matlab仿真
  • ¥15 mars2d在vue3中的引入问题