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

没有消费者,但是当我发布内容时,为什么会立即返回确认? (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.

    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题