ホームページ バックエンド開発 Golang Go での RabbitMQ の使用: 完全ガイド

Go での RabbitMQ の使用: 完全ガイド

Jun 19, 2023 am 08:10 AM
言語を移動 ガイド rabbitmq

最新のアプリケーションが複雑になるにつれて、メッセージングは​​強力なツールになりました。この分野では、RabbitMQ は、異なるアプリケーション間でメッセージを配信するために使用できるメッセージ ブローカーとして非常に人気があります。

この記事では、Go 言語で RabbitMQ を使用する方法を検討します。このガイドでは次の内容について説明します:

  • RabbitMQ の概要
  • RabbitMQ のインストール
  • RabbitMQ の基本概念
  • Go 言語で RabbitMQ を使い始める
  • RabbitMQ と Go 言語の高度な使用法

RabbitMQ の概要

RabbitMQ は、オープン ソースのメッセージ ブローカー ミドルウェアです。これは、アプリケーション間のメッセージングを簡単に処理できる、信頼性が高く、可用性が高く、スケーラブルで使いやすいブローカーです。

RabbitMQ は、AMQP、MQTT、STOMP などの複数のメッセージング プロトコルをサポートしています。また、メッセージ配布、メッセージ永続化、メッセージ確認応答、メッセージ キューイングなどの多くの高度な機能も備えています。

RabbitMQ のインストール

RabbitMQ を使用する前に、次のコマンドを使用してインストールする必要があります:

$ sudo apt-get install rabbitmq-server
ログイン後にコピー

RabbitMQ を Docker コンテナとしてインストールすることもできます。詳細については、公式ウェブサイトをご覧ください。

RabbitMQ の基本概念

RabbitMQ の使用を開始する前に、いくつかの基本概念を理解しましょう。

  • プロデューサー: メッセージを送信するアプリケーション。
  • メッセージ キュー (キュー): RabbitMQ がメッセージを保存するために使用するコンテナー。
  • コンシューマ: メッセージを受信するアプリケーション。
  • Exchange: RabbitMQ がメッセージを受信して​​ルーティングするために使用するコンポーネント。
  • バインディング: スイッチとキューを関連付けるプロセス。
  • ルーティング キー: 一致するキューにメッセージをルーティングするために使用される文字列。
  • メッセージ パターン: ダイレクト、ファンアウト、トピック、ヘッダーなど、メッセージのルーティング方法を指定するルール。

Go 言語で RabbitMQ を始める

Go 言語を使用して、簡単な RabbitMQ プロデューサーとコンシューマーを作成してみましょう。

まず、Go 言語用の RabbitMQ クライアントをインストールする必要があります:

$ go get github.com/streadway/amqp
ログイン後にコピー

次に、RabbitMQ の単純なプロデューサーとして次のコードを使用します:

package main

import (
    "log"

    "github.com/streadway/amqp"
)

func main() {
    // 连接RabbitMQ服务器
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    if err != nil {
        log.Fatalf("Failed to connect to RabbitMQ: %v", err)
    }
    defer conn.Close()

    // 建立通道
    ch, err := conn.Channel()
    if err != nil {
        log.Fatalf("Failed to open a channel: %v", err)
    }
    defer ch.Close()

    // 声明一个队列
    q, err := ch.QueueDeclare(
        "hello", // 队列名称
        false,  // 是否持久化
        false,  // 是否自动删除
        false,  // 是否具有排他性
        false,  // 是否阻塞处理
        nil,    // 额外的参数
    )
    if err != nil {
        log.Fatalf("Failed to declare a queue: %v", err)
    }

    // 发送两条消息
    for _, body := range []string{"Hello", "World"} {
        err = ch.Publish(
            "",    // 交换机名称
            q.Name,  // 队列名称
            false, // 是否强制遵循新的基于名称的路由规则
            false, // 是否立即将消息传递给消费者
            amqp.Publishing{
                ContentType: "text/plain",
                Body:        []byte(body),
            },
        )
        if err != nil {
            log.Fatalf("Failed to publish a message: %v", err)
        }
        log.Printf("Sent a message: %v", body)
    }
}
ログイン後にコピー

たとえば、「hello」という名前のキューに接続し、for ループを使用して 2 つのメッセージをキューに送信します。各メッセージは、Publishing 構造でラップされた単純な文字列です。 ch.Publish()このメソッドは、メッセージをキューにパブリッシュするために使用されます。

ここで、これらのメッセージを受信するコンシューマを作成しましょう:

package main

import (
    "log"

    "github.com/streadway/amqp"
)

func main() {
    // 连接RabbitMQ服务器
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    if err != nil {
        log.Fatalf("Failed to connect to RabbitMQ: %v", err)
    }
    defer conn.Close()

    // 建立通道
    ch, err := conn.Channel()
    if err != nil {
        log.Fatalf("Failed to open a channel: %v", err)
    }
    defer ch.Close()

    // 声明一个队列
    q, err := ch.QueueDeclare(
        "hello", // 队列名称
        false,  // 是否持久化
        false,  // 是否自动删除
        false,  // 是否具有排他性
        false,  // 是否阻塞处理
        nil,    // 额外的参数
    )
    if err != nil {
        log.Fatalf("Failed to declare a queue: %v", err)
    }

    // 将通道设置为接收模式
    msgs, err := ch.Consume(
        q.Name, // 队列名称
        "",     // 消费者名称
        true,   // 自动确认消息
        false,  // 是否具有排他性
        false,  // 是否阻塞处理
        false,  // 额外参数
    )
    if err != nil {
        log.Fatalf("Failed to register a consumer: %v", err)
    }

    // 使用通道消费消息
    forever := make(chan bool)

    go func() {
        for d := range msgs {
            log.Printf("Received a message: %v", string(d.Body))
        }
    }()

    log.Printf("Waiting for messages...")

    <-forever
}
ログイン後にコピー

このコンシューマの例では、「hello」という名前のキューからメッセージを取得し、エコーを実行します。この例では、チャネルの ch.Consume() メソッドを使用してキューからメッセージを消費します。

RabbitMQ と Go 言語の高度な使用法

このセクションでは、RabbitMQ と Go 言語の高度な使用法について説明します。

まず、RabbitMQ と Go 言語を使用してメッセージ確認を実装する方法を見てみましょう。メッセージ確認応答は通常、メッセージが正しく処理されたことを確認するために使用されます。

まず、コンシューマ側で確認モードをオンにする必要があります:

msgs, err := ch.Consume(
    q.Name, // 队列名称
    "",     // 消费者名称
    false,  // 自动确认消息
    false,  // 是否具有排他性
    false,  // 是否阻塞处理
    false,  // 额外参数
)
ログイン後にコピー

手動確認モードでは、コンシューマ側で各メッセージを明示的に確認する必要があります:

for d := range msgs {
    log.Printf("Received a message: %v", string(d.Body))

    // 确认消息
    d.Ack(false)
}
ログイン後にコピー

RabbitMQ の RPC モードを使用して分散 RPC 呼び出しを実装することもできます。 RPC モードでは、クライアント アプリケーションが RabbitMQ にリクエストを送信し、RabbitMQ がリクエストを適切なサーバーに転送し、サーバーがリクエストを処理して応答を返します。

まず、RPC リクエストを受信するスイッチを宣言する必要があります:

ch, err := conn.Channel()
if err != nil {
    log.Fatalf("Failed to open a channel: %v", err)
}
defer ch.Close()

// 声明一个Direct类型的交换机
err = ch.ExchangeDeclare(
    "rpc_exchange", // 交换机名称
    "direct",       // 交换机类型
    true,           // 是否持久化
    false,          // 是否自动删除
    false,          // 是否具有排他性
    false,          // 是否阻塞处理
    nil,            // 额外参数
)
if err != nil {
    log.Fatalf("Failed to declare a exchange: %v", err)
}

// 声明一个接收RPC请求的队列
q, err := ch.QueueDeclare("", false, false, true, false, nil)
if err != nil {
    log.Fatalf("Failed to declare a queue: %v", err)
}

// 将队列绑定到交换机
err = ch.QueueBind(
    q.Name,         // 队列名称
    "rpc_routing",  // 路由键
    "rpc_exchange", // 交换机名称
    false,          // 是否强制遵循新的基于名称的路由规则
    nil,            // 额外参数
)
if err != nil {
    log.Fatalf("Failed to bind a queue: %v", err)
}
ログイン後にコピー

次に、RPC リクエストを処理する関数を作成します:

func rpcHandler(body []byte) []byte {
    log.Printf("Received RPC request: %s", string(body))

    // 处理请求
    result := []byte("Hello, World!")

    return result
}
ログイン後にコピー

次に、次のことを行う必要があります。 write RPC リクエストを受信するコンシューマ:

msg, ok, err := ch.Get(q.Name, true)
if err != nil {
    log.Fatalf("Failed to handle RPC request: %v", err)
}

if !ok {
    log.Printf("No messages available")
    return
}

// 处理RPC请求
response := rpcHandler(msg.Body)

// 发送RPC响应
err = ch.Publish(
    "",              // 交换机名称
    msg.ReplyTo,     // 回调队列名称
    false,           // 是否强制遵循新的基于名称的路由规则
    false,           // 是否立即将消息传递给消费者
    amqp.Publishing{ // 发布消息
        ContentType: "text/plain",
        CorrelationId: msg.CorrelationId,
        Body:        response,
    },
)
if err != nil {
    log.Fatalf("Failed to publish a message: %v", err)
}

log.Printf("Sent RPC response: %v", string(response))
ログイン後にコピー

この例では、ch.Get() メソッドを使用してキューからメッセージを取得し、rpcHandler に送信します。 () 処理メソッド。処理が完了したら、ch.Publish() メソッドを使用して応答をクライアントに送り返します。

結論

RabbitMQ は、アプリケーション間のメッセージングを簡単に処理できる強力なツールです。このガイドでは、Go での RabbitMQ の基本と高度な使用法について説明します。この知識を独自のプロジェクトに適用して、RabbitMQ を使用した効率的なメッセージングを行うことができます。

以上がGo での RabbitMQ の使用: 完全ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? Apr 02, 2025 pm 04:12 PM

大企業または有名なオープンソースプロジェクトによって開発されたGOのどのライブラリが開発されていますか? GOでプログラミングするとき、開発者はしばしばいくつかの一般的なニーズに遭遇します...

GOの浮動小数点番号操作に使用されるライブラリは何ですか? GOの浮動小数点番号操作に使用されるライブラリは何ですか? Apr 02, 2025 pm 02:06 PM

GO言語の浮動小数点数操作に使用されるライブラリは、精度を確保する方法を紹介します...

Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Apr 02, 2025 pm 02:03 PM

Go言語での文字列印刷の違い:printlnとstring()関数を使用する効果の違いはGOにあります...

Go's Crawler Collyのキュースレッドの問題は何ですか? Go's Crawler Collyのキュースレッドの問題は何ですか? Apr 02, 2025 pm 02:09 PM

Go Crawler Collyのキュースレッドの問題は、Go言語でColly Crawler Libraryを使用する問題を調査します。 �...

GoおよびViperライブラリを使用するときにポインターを渡す必要があるのはなぜですか? GoおよびViperライブラリを使用するときにポインターを渡す必要があるのはなぜですか? Apr 02, 2025 pm 04:00 PM

ポインター構文とviperライブラリの使用における問題への取り組みGO言語でプログラミングするとき、特にポインターの構文と使用を理解することが重要です...

GO言語の範囲を使用してマップを通過してマップを保存するのに、なぜすべての値が最後の要素になるのですか? GO言語の範囲を使用してマップを通過してマップを保存するのに、なぜすべての値が最後の要素になるのですか? Apr 02, 2025 pm 04:09 PM

GOのマップイテレーションにより、すべての値が最後の要素になるのはなぜですか? Go言語では、いくつかのインタビューの質問に直面したとき、あなたはしばしば地図に遭遇します...

Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Apr 02, 2025 pm 04:54 PM

redisstreamを使用してGo言語でメッセージキューを実装する問題は、GO言語とRedisを使用することです...

Golandのカスタム構造ラベルが有効になっていないという問題を解決する方法は? Golandのカスタム構造ラベルが有効になっていないという問題を解決する方法は? Apr 02, 2025 pm 12:51 PM

GoLandを使用する場合のGolandのカスタム構造タグの問題に関して、Go Language Developmentに使用する場合、いくつかの構成の問題に遭遇することがよくあります。それらの1つは...

See all articles