go - 没有消费者,但是当我发布某些内容时,为什么会立即返回 ack? (golang/rabbitmq)

标签 go rabbitmq message-queue

下面是我使用的发布商代码。在消息从队列中取出之前需要确认。它应该打印出它收到了来自消费者的 Ack 或 nack(在代码底部)。如果您只是单独运行下面的发布者代码(同时不运行消费者代码),它应该只是挂起,等待 ack 或 nack,但事实并非如此,它会打印出一个 ack ,就好像消费者已经发送了它一样。所以如果我的代码有任何错误,我会很困惑。

对于基本代码,我使用了rabbitmq官方教程中的代码:https://www.rabbitmq.com/tutorials/tutorial-one-go.html

对于代码的 ack/nack 部分,我遵循以下步骤: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)
    }
}

最佳答案

您将发布者确认 ack 和 nack 与消费者端 ack 和 nack 混淆了。

文档指出:

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.

所以您看到的是正确的行为。 RabbitMQ 正在确认消息已到达队列。

关于go - 没有消费者,但是当我发布某些内容时,为什么会立即返回 ack? (golang/rabbitmq),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43470113/

相关文章:

Ajax 请求未发送到 Go Web 服务器

go - 指针的行为

java - 我们能否拥有类似于 RabbitMq 的 Apache Kafka 强大的路由能力?

python - 无法远程访问 RabbitMq 服务器

Rabbitmq + Web stomp 插件与 rpc - 回复

java - 使用队列解耦程序

go - 写连接池

regex - 捕获两个大括号之间的所有数据

C - msgrcv 在收到的消息中添加字符,很奇怪

amazon-web-services - 为 AWS 中的多个消费者选择消息队列方法