Spring AMQPを使用したRabbitMQメッセージのディスパッチ
1. 前書き
このチュートリアルでは、fanoutの概念と、Spring AMQPおよびRabbitMQとのトピック交換について説明します。
高レベルでは、fanout exchangesはbroadcast the same message to all bound queuesになりますが、topic exchangesはpassing messages to a particular bound queue or queuesにルーティングキーを使用します。
このチュートリアルでは、Messaging With Spring AMQPを事前に読むことをお勧めします。
2. ファンアウト交換のセットアップ
2つのキューがバインドされた1つのファンアウト交換を設定しましょう。 この交換にメッセージを送信すると、両方のキューがメッセージを受信します。 ファンアウト交換では、メッセージに含まれるルーティングキーは無視されます。
Spring AMQPを使用すると、キュー、交換、およびバインディングのすべての宣言をDeclarablesオブジェクトに集約できます。
@Bean
public Declarables fanoutBindings() {
Queue fanoutQueue1 = new Queue("fanout.queue1", false);
Queue fanoutQueue2 = new Queue("fanout.queue2", false);
FanoutExchange fanoutExchange = new FanoutExchange("fanout.exchange");
return new Declarables(
fanoutQueue1,
fanoutQueue2,
fanoutExchange,
bind(fanoutQueue1).to(fanoutExchange),
BindingBuilder.bind(fanoutQueue2).to(fanoutExchange));
}
3. トピック交換のセットアップ
次に、それぞれが異なるバインディングパターンを持つ2つのキューを使用してトピック交換を設定します。
@Bean
public Declarables topicBindings() {
Queue topicQueue1 = new Queue(topicQueue1Name, false);
Queue topicQueue2 = new Queue(topicQueue2Name, false);
TopicExchange topicExchange = new TopicExchange(topicExchangeName);
return new Declarables(
topicQueue1,
topicQueue2,
topicExchange,
BindingBuilder
.bind(topicQueue1)
.to(topicExchange).with("*.important.*"),
BindingBuilder
.bind(topicQueue2)
.to(topicExchange).with("#.error"));
}
A topic exchange allows us to bind queues to it with different key patterns.これは非常に柔軟性があり、同じパターンの複数のキュー、または複数のパターンを同じキューにバインドできます。
メッセージのルーティングキーがパターンと一致すると、キューに配置されます。 If a queue has multiple bindings which match the message’s routing key, only one copy of the message is placed on the queue.
バインドパターンでは、アスタリスク(「*」)を使用して特定の位置の単語に一致させるか、ポンド記号(「#」)を使用して0個以上の単語に一致させることができます。
したがって、topicQueue1は、3ワードのパターンを持つルーティングキーを持ち、中央のワードが「重要」であるメッセージを受信します。例:“user.important.error”または“blog.important.notification”.
また、topicQueue2は、エラーという単語で終わるルーティングキーを持つメッセージを受信します。一致する例は、“error”、“user.important.error”、または“blog.post.save.error”.です。
4. プロデューサーのセットアップ
RabbitTemplateのconvertAndSendメソッドを使用して、サンプルメッセージを送信します。
String message = " payload is broadcast";
return args -> {
rabbitTemplate.convertAndSend(FANOUT_EXCHANGE_NAME, "", "fanout" + message);
rabbitTemplate.convertAndSend(TOPIC_EXCHANGE_NAME, ROUTING_KEY_USER_IMPORTANT_WARN,
"topic important warn" + message);
rabbitTemplate.convertAndSend(TOPIC_EXCHANGE_NAME, ROUTING_KEY_USER_IMPORTANT_ERROR,
"topic important error" + message);
};
RabbitTemplateは、さまざまな交換タイプに対して多くのオーバーロードされたconvertAndSend()メソッドを提供します。
ファンアウト交換にメッセージを送信すると、ルーティングキーは無視され、メッセージはすべてのバインドされたキューに渡されます。
トピック交換にメッセージを送信するとき、ルーティングキーを渡す必要があります。 このルーティングキーに基づいて、メッセージは特定のキューに配信されます。
5. コンシューマーの構成
最後に、生成されたメッセージを取得するために、4つのコンシューマー(キューごとに1つ)を設定しましょう。
@RabbitListener(queues = {FANOUT_QUEUE_1_NAME})
public void receiveMessageFromFanout1(String message) {
System.out.println("Received fanout 1 message: " + message);
}
@RabbitListener(queues = {FANOUT_QUEUE_2_NAME})
public void receiveMessageFromFanout2(String message) {
System.out.println("Received fanout 2 message: " + message);
}
@RabbitListener(queues = {TOPIC_QUEUE_1_NAME})
public void receiveMessageFromTopic1(String message) {
System.out.println("Received topic 1 (" + BINDING_PATTERN_IMPORTANT + ") message: " + message);
}
@RabbitListener(queues = {TOPIC_QUEUE_2_NAME})
public void receiveMessageFromTopic2(String message) {
System.out.println("Received topic 2 (" + BINDING_PATTERN_ERROR + ") message: " + message);
}
We configure consumers using the @RabbitListener annotation.ここで渡される唯一の引数は、キューの名前です。 ここでは、消費者は交換またはルーティングキーを認識しません。
6. サンプルの実行
サンプルプロジェクトはSpring Bootアプリケーションであるため、RabbitMQへの接続とともにアプリケーションを初期化し、すべてのキュー、交換、およびバインディングをセットアップします。
デフォルトでは、アプリケーションはポート5672のローカルホストで実行されるRabbitMQインスタンスを想定しています。 これと他のデフォルトをapplication.yamlで変更できます。
私たちのプロジェクトは、リクエスト本文にメッセージを含むPOSTを受け入れるURI(/broadcast)でHTTPエンドポイントを公開します。
ボディ「Test」を使用してこのURIにリクエストを送信すると、出力に次のようなものが表示されます。
Received fanout 1 message: fanout payload is broadcast
Received topic 1 (*.important.*) message: topic important warn payload is broadcast
Received topic 2 (#.error) message: topic important error payload is broadcast
Received fanout 2 message: fanout payload is broadcast
Received topic 1 (*.important.*) message: topic important error payload is broadcast
もちろん、これらのメッセージが表示される順序は保証されていません。
7. 結論
このクイックチュートリアルでは、Spring AMQPとRabbitMQによるファンアウトとトピックの交換について説明しました。
このチュートリアルの完全なソースコードとすべてのコードスニペットは、GitHub repositoryで入手できます。