Spring AMQPによるRabbitMQメッセージの配信

Spring AMQPを使用したRabbitMQメッセージのディスパッチ

1. 前書き

このチュートリアルでは、fanoutの概念と、Spring AMQPおよびRabbitMQとのトピック交換について説明します。

高レベルでは、fanout exchangesbroadcast the same message to all bound queuesになりますが、topic exchangespassing 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. プロデューサーのセットアップ

RabbitTemplateconvertAndSendメソッドを使用して、サンプルメッセージを送信します。

    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で入手できます。