2017-04-18 1 views
1

以下は、私が使用する出版社のコードです。メッセージがキューから取り出される前に、acksが必要です。コンシューマーからのAckまたはナック(コードの最後に)を受け取ったことを印刷することを想定しています。下にパブリッシャーコードを単独で実行すると(コンシューマーコードを同時に実行せずに)、ハングアップしたり、待ち受けを待っていると思われますが、コンシューマーコードを送ったかのようにackを出力します。だから私はコードの一部が間違っていると混乱している。私はRabbitMQの公式チュートリアルからコードを使用する基本コードの場合 消費者はいませんが、何かを公開するとすぐにackが返されます。なぜですか? (golang/rabbitmq)

は:あなたがして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:[email protected]: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) 
    } 
} 

答えて

2

:コードのACK/NACKの部分についてはhttps://www.rabbitmq.com/tutorials/tutorial-one-go.html

は、私はこれを続きます消費者側の嫌がらせと搾取。

ドキュメントの状態:ルーティング不能なメッセージの場合は

、ブローカーは一度 交換は任意のキューにメッセージをルーティングしないが、(キューの空 リストを返します)を検証し確認を発行します。メッセージが必須として公開されている場合は、basic.ackの前に basic.returnがクライアントに送信されます。否定応答(basic.nack)の場合も同じです( )。

ルーティング可能なメッセージの場合、すべてのキューでメッセージが として受け入れられると、basic.ackが送信されます。永続メッセージを永続的な キューにルーティングする場合、これはディスクに永続することを意味します。ミラーリングされたキューの場合、これはすべてのミラーがメッセージを受け入れたことを意味する を意味します。

正しい動作が表示されています。 RabbitMQは、メッセージがキューに到着したことを確認しています。

+0

メッセージが消費されて確認されるまで、ラビットがパブを受け入れるのを待っていた場合、メッセージキューの目的全体が完全に無効になるためです。 – Adrian

関連する問題