RabbitMQ Java client には次の概念があります。
Connection
-RabbitMQサーバーインスタンスへの接続Channel
-???私は関係を理解しようとしています、さらに重要なのは、それらの間の関連付けです。
Channel
が何であるかはまだわかりませんが、これはあなたがパブリッシュして消費する構造であり、オープン接続から作成されるという事実を除いてです。誰かが「チャンネル」が何を表しているのかを説明してくれると、いくつかのことがわかりやすくなります。ここで助けてくれてありがとう!
Connection
は、メッセージブローカーへの実際のTCP接続を表しますが、Channel
はその内部の仮想接続(AMPQ接続)です。このようにして、TCP接続でブローカーをオーバーロードすることなく、アプリケーション内で必要な数の(仮想)接続を使用できます。
すべてに1つのChannel
を使用できます。ただし、複数のスレッドがある場合は、スレッドごとに異なるChannel
を使用することをお勧めします。
JavaクライアントAPIガイドのチャネルスレッドセーフティ :
チャネルインスタンスは、複数のスレッドで安全に使用できます。チャンネルへのリクエストはシリアル化され、一度に1つのスレッドのみがチャンネルでコマンドを実行できます。それでも、アプリケーションは、複数のスレッド間で同じチャネルを共有するのではなく、スレッドごとにチャネルを使用することを選択する必要があります。
Channel
とQueue
の間に直接の関係はありません。 Channel
は、AMQPコマンドをブローカーに送信するために使用されます。これはキューの作成などの場合がありますが、これらの概念は結び付けられていません。
各Consumer
は、コンシューマスレッドプールから割り当てられた独自のスレッドで実行されます。複数のコンシューマーが同じキューにサブスクライブしている場合、ブローカーはラウンドロビンを使用してそれらの間でメッセージを均等に配信します。 チュートリアル2: "作業キュー" を参照してください。
同じConsumer
を複数のキューに接続することもできます。消費者はコールバックとして理解できます。これらは、コンシューマがバインドされているキューにメッセージが到着するたびに呼び出されます。 Java Clientの場合、各コンシューマにはhandleDelivery(...)
メソッドがあり、これはコールバックメソッドを表します。通常は、DefaultConsumer
をサブクラス化し、handleDelivery(...)
をオーバーライドします。注:同じConsumerインスタンスを複数のキューにアタッチすると、このメソッドは異なるスレッドによって呼び出されます。そのため、必要に応じて同期に注意してください。
ここでは、AMQPプロトコルが「内部で」行うことを概念的によく理解しておくと役立ちます。 AMQP 0.9.1が展開することを選択したドキュメントとAPIは、これを特に混乱させるため、質問自体は多くの人が取り組まなければならないものです。
TL; DR
connectionは、AMQPサーバーとの物理的にネゴシエートされたTCPソケットです。適切に実装されたクライアントには、アプリケーションごとにこれらのいずれかがあり、スレッドセーフで、スレッド間で共有可能です。
channelは、接続上の単一のアプリケーションセッションです。スレッドには、これらのセッションが1つ以上あります。 AMQPアーキテクチャ0.9.1では、これらのスレッドはスレッド間で共有されないため、作成したスレッドが終了したらクローズ/破棄する必要があります。また、さまざまなプロトコル違反が発生すると、サーバーによって閉じられます。
consumerは、特定のチャネル上の「メールボックス」の存在を表す仮想構造です。コンシューマを使用すると、特定のキューからそのチャネルエンドポイントにメッセージをプッシュするようブローカーに指示します。
接続の事実
まず、他の人が正しく指摘しているように、connectionは、サーバーへの実際のTCP接続を表すオブジェクトです。接続はAMQPのプロトコルレベルで指定され、ブローカーとのすべての通信は1つ以上の接続を介して行われます。
チャンネルの事実
Channelは、RabbitMQブローカーと通信するためにアプリの各部分に対して開かれるアプリケーションセッションです。単一の接続で動作し、ブローカーとのセッションを表します。
消費者の事実
コンシューマは、AMQPプロトコルによって定義されたオブジェクトです。これはチャネルでも接続でもありません。代わりに、特定のアプリケーションがメッセージをドロップするための一種の「メールボックス」として使用するものです。
コンシューマスレッドプールの意味では、Javaクライアントは、クライアントが実行するようにプログラムしたものと似た動作をしていると考えられます(私のものは.Netクライアントに基づいていましたが、大幅に変更されていました)。
AMQPモデルのすべての側面を説明するこの記事を見つけましたが、そのうちの1つはチャネルです。私の理解を締めくくるのに非常に役立ちました
https://www.rabbitmq.com/tutorials/amqp-concepts.html
一部のアプリケーションでは、AMQPブローカーへの複数の接続が必要です。ただし、多くのTCP接続を同時に開いたままにすると、システムリソースが消費され、ファイアウォールの構成が難しくなるため、望ましくありません。 AMQP 0-9-1接続は、「単一のTCP接続を共有する軽量接続」と考えることができるチャネルと多重化されます。
処理に複数のスレッド/プロセスを使用するアプリケーションの場合、スレッド/プロセスごとに新しいチャネルを開き、それらの間でチャネルを共有しないことは非常に一般的です。
特定のチャネルでの通信は別のチャネルでの通信とは完全に分離されているため、すべてのAMQPメソッドは、メソッドが対象とするチャネル(したがって、たとえば、どのイベントハンドラーを呼び出す必要があるか)を判別するためにクライアントが使用するチャネル番号も保持します。