お金をかけずにサーバーの勉強をしよう

RabbitMQのクラスタ化(番外編)

2023年4月10日

メニューへ戻る

RabbitMQでクラスタを作りましたけど、クライアントはこれをどう使えば良いのでしょう。

RabbitMQでメッセージを受け渡し」で RabbitMQのインストールをし、
RabbitMQのクラスタ化(前編)」でサーバーを 2台使って冗長化し、
RabbitMQのクラスタ化(中編)」でデータが冗長化されているキューを作成し(3台のクラスタになりました)。
RabbitMQのクラスタ化(後編)」でクラスタの動作確認をしました。

こうして RabbitMQのサーバーは冗長化できた訳です。
こんなのが。
RabbitMQのクラスタ図 1


けど、開発言語で作っているクライアントプログラムではどこに接続しに行けば良いのですかね。

例として、ここの実験で使った Pythonのスクリプトは RabbitMQのサイトにあった雛形とほぼ同じで、接続先の記述はこんな風でした。

RabbitMQのオフィシャルサポート対象になっている「Pika」ってライブラリが使われています。

[send.py]

#!/usr/bin/python3
import pika

# virtual_host でバーチャルホスト名を指定
connection = pika.BlockingConnection( pika.ConnectionParameters( host="RabbitMQ3", virtual_host="/testvhost", credentials=pika.PlainCredentials('subro', 'password') ))
channel = connection.channel()

# routeing_key でキュー名を指定。
channel.basic_publish(exchange='',
                      routing_key='test',
                      body='Hello World!')

print(" [x] Sent 'Hello World!'")

connection.close()

BlockingConnectionというクラスのコンストラクタに Connection Parametersというクラスオブジェクトを渡している。
Connection Parametersのコンストラクタに「host」って str値を渡していますね。

これを[RabbitMQ1][RabbitMQ2][RabbitMQ3]を全部割り当てると、よろしく障害中のサーバーを避けながら分散してログインしてくれるんでしょうか。

だけど、上記 2つのクラスの APIドキュメントを読んでも、クラスタアクセスに関する記載がないようです。(見つけられてないだけかも)

でも Pikaのドキュメントには、クラスタアクセスさせる Pythonスクリプトの例がありました。
Using the Blocking Connection with connection recovery with multiple hosts

2つの例がありました。

  1. whileを使ってサーバーのリストを順繰りに繋がるまで繰り返す方法
  2. retryデコレーター(要 retryモジュール)(以下同文)

どちらの例でも、BlockingConnectionクラスの機能にはサーバーのリストから生きているのを見つける機能はなさげで、例外をしてリトライ機能を外側に実装していますね。

Pikaを使う場合は基本的に上の例を真似した形の実装になりそうです。


試しに Javaの例を見てみました。

Javaでは、RabbitMQのドキュメントに例があります。
Using List of Endpoints

これは「ConnectionFactory」クラスの「newConnection」メソッドに、複数のサーバーのリストを渡すようにしている例となっています。

同メソッドのドキュメントはこれです。
newConnection

説明にはこうあります。

Create a new broker connection, picking the first available address from the list provided by the AddressResolver. If automatic connection recovery is enabled, the connection returned by this method will be Recoverable. Future reconnection attempts will pick a random accessible address provided by the AddressResolver.

こちらのメソッドには、生きているサーバーを見つけ出す機能まで実装されているようですね。

Pythonでもそうしたい!と無い物ねだりしても始まりませんし、これはあるものでできることをする他ありませんね。
(Pythonには RabbitMQにアクセスできるライブラリが他にもあります)


この調子で行くと、他の言語でもクラスタ環境へのアクセスについては、まぁまぁ楽な所までライブラリ側で実装してくれていると予想します。

少なくともラッピングした関数なりメソッドなり作ってしまえば、実際の利用については非常に少ないコードで RabiitMQへの接続はできると思います。


気になるのは、接続先が見つかるまでのディレイやら、データ転送中の障害にどこまで追従するかです。

これはプログラムを書いてからテストしまくる他ないですが、すみません、そこまでの気力が無くてこの話はこれでおしまいとします。