コンテナ化された運用とメンテナンス: 高可用性 RabbitMQ クラスターを構築するための Docker Compose ガイド
序文
コンピューターの世界では、メッセージングは魔法の旅のようなもので、メッセージはまるで魔法のように運ばれるかのようにシステム間を行き来します。今日は、ファンタジーな冒険に満ちた分野、RabbitMQ クラスターの実装に入ります。
RabbitMQ がメッセンジャーのウサギであると想像してください。RabbitMQ は賢くて柔軟なだけでなく、ある場所から別の場所にメッセージを素早く届けることができます。RabbitMQ クラスターは強力なウサギのファミリーのようなもので、ウサギのマジック ショーのように、メッセージが決して失われないように緊密に連携します。
この素晴らしい旅では、RabbitMQ クラスターを公開し、全能の魔法の軍隊のように、高負荷を処理でき、フォールトトレラントな強力なメッセージング システムを構築する方法を一緒に探索します。
この楽しくてやりがいのあるメッセージング アドベンチャーでウサギの友達をフォローする準備をしましょう! この素晴らしい世界では、メッセージングの魔法が無限であることに気づくでしょう。
RabbitMQ については、まずいくつかの知識ポイントを説明します。
RabbitMQ 関連のナレッジポイント
❓: Exchange のタイプの違いは何ですか
-
直接交換:
- メッセージのルーティング キーと正確に一致するキューにメッセージを送信します。
- メッセージは、そのルーティング キーが交換機にバインドされたキューのルーティング キーと正確に一致する場合にのみキューに送信されます。
- ルーティング キーの正確な一致が必要な状況に適しています。
-
トピック交換:
- ワイルドカードを使用して、メッセージのルーティング キーをバインドされたキューと照合します。
- ワイルドカード文字「*」(1 つの単語に一致) および「#」(複数の単語に一致) を使用して、ルーティング キーのパターンを定義できます。
- ルーティング キーの柔軟なマッチングが必要な状況に適しており、複雑なメッセージ ルーティングをサポートします。
-
ファンアウト交換:
- メッセージのルーティング キーを無視して、受信したメッセージをすべてのバインドされたキューにブロードキャストします。
- 交換にバインドされたすべてのキューは、メッセージの同じコピーを受信します。
- メッセージをすべてのキューにブロードキャストする必要がある状況に適しています。
-
ヘッダー交換:
- ルーティング キーを使用するのではなく、メッセージのヘッダー属性を照合に使用します。
- メッセージのヘッダーにキーと値のペアの属性を設定し、キューにバインドするときに一致するヘッダー属性を設定できます。
- メッセージヘッダー属性に基づいたルーティングに適しています。
適切な交換タイプの選択は、アプリケーションのアーキテクチャとメッセージングのニーズによって異なります。通常、直接接続スイッチとトピック スイッチを使用すると、ほとんどのシナリオを満たすことができます。複数のキュー間でメッセージをブロードキャストする必要がある場合は、ファンアウト エクスチェンジャーを使用できます。メッセージ ヘッダー属性に基づいて照合する必要がある場合は、ヘッダー エクスチェンジャーを使用できます。
スイッチ タイプは一度設定すると、通常は変更できないことに注意してください。したがって、スイッチ タイプを選択するときは、実際のニーズに基づいてトレードオフと計画を立てる必要があります。
❓:ポリシーとは
RabbitMQ の「ポリシー」は、エクスチェンジ、キュー、バインディングの動作の管理と構成を自動化するためのメカニズムです。ポリシーを使用すると、RabbitMQ クラスター内で一連のルールを定義できます。これらのルールは、交換、キュー、バインディングに自動的に適用され、特定の条件が満たされた場合に事前定義されたアクションを実行します。これにより、管理が簡素化され、効率が向上し、一貫性が確保されます。
ポリシーは、キューのミラーリング、有効期限、メッセージの最大長、デッドレターキューなど、さまざまな方法で使用できます。ポリシーを設定すると、各ノードの構成を手動で変更することなく、クラスター内の複数のノードに同じ構成を自動的に適用できます。
戦略の一般的な使用法をいくつか示します。
-
ミラー キュー ポリシー:キューが宣言されたときにキューをミラー キューとして自動的に設定できるため、メッセージの冗長バックアップと高可用性が実現します。
-
キュー有効期限ポリシー:キュー内のメッセージの有効期限を設定できます。メッセージの有効期限が切れると、RabbitMQ はキューからメッセージを自動的に削除します。
-
メッセージの最大長ポリシー:キュー内のメッセージの最大長を制限できます。キュー内のメッセージの数が設定された最大長に達すると、新しいメッセージは破棄されるか、デッド レターとして処理されます。
-
デッドレターキュー戦略:キュー内で消費できないメッセージをデッドレターキューに自動的に送信して、さらに処理することができます。
-
優先キュー ポリシー:メッセージの優先順位を設定し、優先順位に基づいてメッセージを異なるキューに入れることができます。
等
ポリシーを設定するには、RabbitMQ 管理プラグインの管理インターフェイスを使用するか、 などのコマンド ライン ツールを使用できますrabbitmqctl
。ポリシーを設定することで、管理と構成を自動化し、手動操作の必要性を減らし、システムの信頼性と保守性を向上させることができます。
❓: ポリシーの設定方法
パラメータの説明:
-
パターン:
- これは、エクスチェンジャー、キュー、およびバインディングを照合するために使用されるパターンです。
*
ワイルドカード文字と を使用できます#
。 - たとえば、 を使用して、で始まる
amq.*
すべてのエクスチェンジャを照合できます。amq.
- これは、エクスチェンジャー、キュー、およびバインディングを照合するために使用されるパターンです。
-
意味:
- これは、ポリシー定義を含む JSON オブジェクトです。特定のパラメータと値は、設定するポリシーのタイプによって異なります。
- たとえば、ミラー キュー ポリシーを作成している場合は、
ha-mode
その他の関連パラメータを定義できます。
-
ha-mode (ミラーキューモード):
- 使用法:
ha-mode = all
またはha-mode = exactly
ha-mode = nodes
- 機能: メッセージの冗長バックアップと高可用性を実現するために、キューがミラー キューであるかどうかを定義します。
all
: キューをミラーキューとして設定し、すべてのノードでキューのミラーを作成します。exactly
: キューをミラーキューとして設定し、作成するミラーノードの数を指定します。nodes
: キューをミラーキューとして設定し、ミラーを作成するノードを指定します。
- 使用法:
-
ha-params (ミラーキューパラメータ):
- 使用法:
ha-params = ["node1", "node2"]
- 機能:
ha-mode = nodes
キューミラーリングを作成するノードリストを指定するために使用されます。
- 使用法:
-
期限切れ (メッセージの有効期限):
- 使用法:
expires = 3600000
(ミリ秒) - 機能: キュー内のメッセージの有効期限を定義すると、期限切れのメッセージは自動的に削除されます。
- 使用法:
-
message-ttl (メッセージ生存時間):
- 使用法:
message-ttl = 60000
(ミリ秒) - 機能: キュー内のメッセージの生存時間を定義します。この時間を超えたメッセージは自動的に削除されます。
- 使用法:
-
max-length (メッセージの最大数):
- 使用法:
max-length = 1000
- 機能: キュー内のメッセージの最大数を制限します。キュー内のメッセージ数が指定された値に達すると、新しいメッセージは破棄されるか、デッド レターとして処理されます。
- 使用法:
-
Dead-Letter-Exchange (デッドレターエクスチェンジ):
- 使用法:
dead-letter-exchange = dlx_exchange
- 機能: デッドレターキュー内のメッセージの送信先の交換機を指定します。
- 使用法:
-
デッドレタールーティングキー (デッドレタールーティングキー):
- 使用法:
dead-letter-routing-key = dlx_routing_key
- 機能: デッドレターキュー内のメッセージが使用するルーティングキーを指定します。
- 使用法:
-
max-length-bytes (メッセージの最大バイト数):
- 使用法:
max-length-bytes = 102400
- 機能: キュー内のメッセージの合計バイト数を制限します。キュー内のメッセージの合計バイト数が指定された値に達すると、新しいメッセージは破棄されるか、デッド レターとして処理されます。
- 使用法:
-
遅延モード (遅延モード):
- 使用法:
lazy-mode = on
またはlazy-mode = off
- 機能: 遅延モードを有効または無効にします。遅延モードは、メモリ使用量を削減するためにキュー内のメッセージをディスクに保存するために使用されます。
- 使用法:
-
キューモード (キューモード):
- 使用法:
queue-mode = lazy
またはqueue-mode = default
lazy
機能:遅延モードとデフォルト モードを示すキューの動作モードを定義しますdefault
。
- 使用法:
-
優先度:
- ポリシーの優先度を指定するために使用されます。複数のポリシーが一致する場合、優先度の高いポリシーが低いポリシーをオーバーライドします。
- 優先度は通常整数で表され、値が小さいほど優先度が高いことを示します。
-
適用先:
- ポリシーを適用するオブジェクト (エクスチェンジ、キュー、バインディング) を指定するために使用されます。
- 「エクスチェンジ」、「キュー」、または「すべて」を選択できます。
私が上記のことを言っている理由は、主に私が追加した戦略であるクラスターを実装するためです。キューが個別に作成された場合、キューはデフォルトで現在のノードにのみ属するため、ミラーリングまたはこの戦略に依存する必要があるからです。達成する
docker-compose は RabbitMQ クラスターを構築します
docker-compose.yml ファイルを作成する
version: '3'
services:
rabbitmq-node1:
image: rabbitmq:3.9.22-management
container_name: rabbitmq-node1
hostname: rabbitmq-node1
# command: rabbitmq-server --erlang-cookie=97c78681-3394-208f-9d04-b86cb68f9c60
entrypoint: /bin/bash -c "rabbitmq-server rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbit@rabbitmq-node1.pid"
ports:
- "5672:5672"
- "15672:15672"
volumes:
- ./rabbitmq_delayed_message_exchange-3.9.0.ez:/plugins/rabbitmq_delayed_message_exchange-3.9.0.ez
- ./.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie
- ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
environment:
- RABBITMQ_DELAYED_MESSAGE_ENABLED=true
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=123456
- RABBITMQ_PLUGINS=--offline rabbitmq_delayed_message_exchange
- RABBITMQ_NODENAME=rabbit@rabbitmq-node1 # 节点名称
# - RABBITMQ_USE_LONGNAME=true #它用于告诉 RabbitMQ 是否使用长节点名称。
networks:
- rabbitmq-network
rabbitmq-node2:
image: rabbitmq:3.9.22-management
container_name: rabbitmq-node2
hostname: rabbitmq-node2
entrypoint: /bin/bash -c "rabbitmq-server rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbit@rabbitmq-node2.pid && rabbitmqctl join_cluster rabbit@rabbitmq-node1"
# command: rabbitmq-server --erlang-cookie=97c78681-3394-208f-9d04-b86cb68f9c60
ports:
- "5673:5672"
- "15673:15672"
volumes:
- ./rabbitmq_delayed_message_exchange-3.9.0.ez:/plugins/rabbitmq_delayed_message_exchange-3.9.0.ez
- ./.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie
- ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
environment:
- RABBITMQ_DELAYED_MESSAGE_ENABLED=true
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=123456
- RABBITMQ_PLUGINS=--offline rabbitmq_delayed_message_exchange
- RABBITMQ_NODENAME=rabbit@rabbitmq-node2 # 节点名称
# - RABBITMQ_USE_LONGNAME=true #它用于告诉 RabbitMQ 是否使用长节点名称。
networks:
- rabbitmq-network
depends_on:
- rabbitmq-node1
rabbitmq-node3:
image: rabbitmq:3.9.22-management
container_name: rabbitmq-node3
hostname: rabbitmq-node3
# command: rabbitmq-server --erlang-cookie=97c78681-3394-208f-9d04-b86cb68f9c60
entrypoint: /bin/bash -c "rabbitmq-server rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbit@rabbitmq-node3.pid && rabbitmqctl join_cluster rabbit@rabbitmq-node1"
ports:
- "5674:5672"
- "15674:15672"
volumes:
- ./rabbitmq_delayed_message_exchange-3.9.0.ez:/plugins/rabbitmq_delayed_message_exchange-3.9.0.ez
- ./.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie
- ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
environment:
- RABBITMQ_DELAYED_MESSAGE_ENABLED=true
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=123456
- RABBITMQ_PLUGINS=--offline rabbitmq_delayed_message_exchange
#被废弃了 - RABBITMQ_ERLANG_COOKIE=97c78681-3394-208f-9d04-b86cb68f9c60 # 为了确保集群节点通信,需要设置相同的 erlang-cookie
- RABBITMQ_NODENAME=rabbit@rabbitmq-node3 # 节点名称
# - RABBITMQ_USE_LONGNAME=true #它用于告诉 RabbitMQ 是否使用长节点名称。
networks:
- rabbitmq-network
depends_on:
- rabbitmq-node1
networks:
rabbitmq-network:
driver: bridge
⚠: ここで使用されるマウント。1 つ目は実装された遅延キュー プラグインです。2 つ目は mount に必要です。cookie
これはcookie
任意であり、3 つ目は構成ファイルです。
上記のステートメントの一部は次のように説明されます
entrypoint: /bin/bash -c "rabbitmq-server rabbitmqctl wait /var/lib/rabbitmq/mnesia/[email protected] && rabbitmqctl join_cluster rabbit@rabbitmq-node1"
: 待ってからクラスターに参加しますRABBITMQ_PLUGINS=--offline rabbitmq_delayed_message_exchange
:ロードするプラグインを指定し、事前にダウンロードしたプラグインをロードしますRABBITMQ_DELAYED_MESSAGE_ENABLED=true
: メッセージ遅延機能の開始
Rabbitmq.conf ファイルを作成する
# 配置内容
# 这个配置的作用是禁用 "guest" 用户对本地(loopback)的访问。
loopback_users.guest = false
listeners.tcp.default = 5672
# 这个配置指定了集群节点之间的发现机制。`rabbit_peer_discovery_classic_config` 表示使用经典配置方式来进行节点发现。
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
# 这个配置指定了集群中的节点,`rabbit@rabbitmq-node1` 表示第一个节点的名称和主机地址。
cluster_formation.classic_config.nodes.1 = rabbit@rabbitmq-node1
cluster_formation.classic_config.nodes.2 = rabbit@rabbitmq-node2
cluster_formation.classic_config.nodes.3 = rabbit@rabbitmq-node3
⚠: 上記のファイルは同じディレクトリに存在する必要があります
プロジェクトにクラスタ接続を実装する方法
クラスター接続を実装する場合、go と java ではまだ異なりますが、nginx を使用して負荷分散を行うこともできますし、RabbitMQ にも独自の実装があります
⚠: これを実現するには、mysql に接続するのと同じように、nginx モジュールに stream モジュールを追加する必要があります。