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.

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

报告相同问题?

悬赏问题

  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥20 Python安装cvxpy库出问题
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥15 python天天向上类似问题,但没有清零
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题