RabbitMQ Exchangeについて - 発展編 -
さて、今回は、Exchangeについてより詳しく見て行く事にします。
Exchangeはメッセージを受け取る役割を果たすコンポネントですが、
下記の種類があります。
Direct Exchange
メッセージをルーティングキーでキューにバインディングします。
ルーティングキーにワイルドカードは使えず、完全一致でメッセージのルーティングを行います。
同じルーティングキーで複数のキューにルーティングすることも可能です。
(その場合、fanoutと同じ挙動になる)
例)usa.weather.news というルーティングキーを持ったメッセージをupdateキューにバインディングする。
Fanout Exchange
エクスチェンジにバインドされたすべてのキューにメッセージをルーティング
ルーティングキーは無視されます。
複数のキューに同じメッセージをブロードキャストしたい場合に利用します。
例)EX1 に届いたメッセージは、すべてQ1,Q2,Q3に同様に配送する。メッセージに設定された、ルーティングキーなどは考慮されません。
Topic Exchange
ルーティングキーを使ってDirect Exchangeよりも細かいバインディング設定が可能です。
usa.news, usa.weather, usa.#
のようななルーティングキーを設定し、キューに対して
配送ルールを設定することが可能です。
ルーティングサンプルです。
[publisher A]
usa.news.weather のルーティングキーでメッセージを送信...(A)
[publisher B]
usa.news.business のルーティングキーでメッセージを送信...(B)
[consumer]
usa.# のルーティングキーでメッセージを取得するバインディングを行った場合(A)、(B)のメッセージとも取得することができます。
一方で、usa.news.weatherのルーティングキーでキューに対してバインディングを行った場合、(A)のメッセージのみ取得します。
※ルーティングキーでバインディングするため、特定のQueueをせずに
ルーティングキーの指定のみでッセージを送信することも可能です。
そのためTopic Exchangeを使う場合は、channel.queueDeclare() メソッドを利用して、
動的にキューを作成し、そこにメッセージをパブリッシュしてもよいです。
例えば下記のような一時キューが作成されます。
amq.gen-U0srCoW8TsaXjNh73pnVAw==.
その際、一時的なキューは、コンスーマが切断された際に削除されるよう、第三引数のexclusive=trueとするとよいです。
val queueName = channel.queueDeclare("", true, true, false, null).getQueue();
ルーティングキューに合わせたConsumerを作成してキューを監視していればOKですが、一時キューを利用するため、
コンスーマが落ちてしまうと、メッセージが失われてしまうので、オススメはしません。
本番では、ちゃんとdurableなExchangeやQueueを用意して運用した方が良いと思います。
まあでもTopic Exchangeが一番柔軟で、使いやすいのかもしれません。
Header Exchange
任意のヘッダの値を比較することで、ExchangeとQueueの間のバインディングを
行います。
ルーティングキーは無視されます。
キューを宣言する際に、x-match値をargumentに設定します。
バインディングを行う際に、任意のヘッダを作成し、
そのヘッダにマッチするヘッダをメッセージが持っていれば、
キューにルーティングされます。
1. キューを宣言→ x-match:all or any をセット
- all の場合、すべてのargument条件にマッチしていれば、宣言したキューにルーティング
- any の場合、どれかのargument条件にマッチしていれば、宣言したキューにルーティング
2. Echange と1で宣言したキューとのbindingを作成
- binding作成時にargumentでルーティングするargumentを指定
- 例)hoge:test1, foo:test2 の二つを設定するとする。
- メッセージを送る。 そのメッセージのargument にhoge:test1 だけ指定してあった 場合、1でanyの場合はルーティングされるが、allの場合はルーティングされない。1でallが設定された場合は、hoge:test1, foo:test2両方が指定されないと、宣言されたキューにルーティングされない。
ルーティングキーではなく、メッセージヘッダの値によってバインディングを行うためのEchangeです。
メッセージの属性をヘッダー使って送る場合、それに合わせてルーティングを変えたいといった場合に有効です。
topic exchangeにしておけばたいていのルーティングには対応できます。
シンプルな構成だと、Direct Echangeでも大丈夫でしょう。
それよりも、メッセージの可用性を担保するように設計する方が重要だと思います。
Exchangeについては以上です。
次は。。。クラスタリングとか、可用性を高める方法について超訳していきます!
チャオ!