[SpringBoot MQシリーズ] RabbitListenerの消費者の使用の基本的なジェスチャー紹介

[MQシリーズ] RabbitListenerの消費者の使用の基本的なジェスチャー紹介

もちろん、あなたがSpringBoot環境の消費者を持っている必要がでのRabbitMQメッセージング姿勢を導入する前に、消費が持つ、比較的簡単であると言うことができる、送信がされているので、@RabbitListenerあなたは基本的にビジネスの開発ニーズの90%以上を満たすことができ、注釈

ここでは、見て@RabbitListenerのジェスチャーの最も一般的な用途

I. 配置

SpringBootは、最初に、後続のプレゼンテーションのためのプロジェクトを作成します

依存コンフィギュレーション・ファイルのpom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <!-- 注意,下面这个不是必要的哦-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/libs-snapshot-local</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone-local</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-releases</id>
        <name>Spring Releases</name>
        <url>https://repo.spring.io/libs-release-local</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

ではapplication.yml、設定ファイル、RabbitMQの関連の属性を追加します

spring:
  rabbitmq:
    virtual-host: /
    username: admin
    password: admin
    port: 5672
    host: 127.0.0.1

II。消費者の姿勢

この記事では、証明するために、特定のシナリオを組み合わせ、実用上のターゲットとなります@RabbitListenerこのコメントいくつかの属性ので、ジェスチャーの使用をか理解していない、あなたがこの記事を読んで見つけることができません心配を行い、次は一つずつ来るください。

0モックデータ

個人消費は、データがない、どのように過ごすには?我々は最初のステップ、メッセージプロデューサを作成するので、あなたは、その後の使用の消費者のテストのために、交換機へデータを書き込むことができます

主にトピックモデルでBenpian消費について説明する(需要がある場合は、いくつかの他のモデルは、ほとんど差を使用し、その後、パディング続きます)

@RestController
public class PublishRest {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping(path = "publish")
    public boolean publish(String exchange, String routing, String data) {
        rabbitTemplate.convertAndSend(exchange, routing, data);
        return true;
    }
}

休息するための簡単なインタフェースを提供し、あなたがデータをプッシュするためにどの為替指定し、キーのルートを開発することができます

1.ケース1:交換は、キューがすでに存在しています

消費者のために、彼らは本当に送信者によって定義される交流/破壊、の作成を管理する必要があります。一般的に、消費者はより多くの定義と交流キューを含むと結合、自分のキューに関係しており、この直接RabbitMQのコンソールで操作することができるプロセスああ

したがって、実際の開発プロセス、交換キュー対応する結合関係と既に存在する可能性が非常に高い場合、コードは、追加の処理を必要としません。

次のようにこのシナリオでは、消費データは、我々は、非常に、非常にシンプルと言うことができます。

/**
 * 当队列已经存在时,直接指定队列名的方式消费
 *
 * @param data
 */
@RabbitListener(queues = "topic.a")
public void consumerExistsQueue(String data) {
    System.out.println("consumerExistsQueue: " + data);
}

注釈が直接に指定されqueuesたパラメータができ、列名のパラメータ値(QUEUENAME)

2.ケース2:キューは存在しません。

キューは自動削除プロパティがfalseである場合には、上記のシナリオを使用すると、より適切であり、このプロパティがtrueの場合しかし、何のコンシューマ・キューは自動的に削除されますがあり、このときは、上記の位置は、以下を得ることができます異常な

キューは存在しません。

通常、このシナリオでは、我々は以下の通りであるキューを作成するためのイニシアチブをとる、およびExchangeとの結合関係を確立する必要がある@RabbitListener推奨姿勢

/**
 * 队列不存在时,需要创建一个队列,并且与exchange绑定
 */
@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "topic.n1", durable = "false", autoDelete = "true"),
        exchange = @Exchange(value = "topic.e", type = ExchangeTypes.TOPIC),
        key = "r"))
public void consumerNoQueue(String data) {
    System.out.println("consumerNoQueue: " + data);
}

コメントは、キュー内で宣言、および結合関係はとても魔法である確立します!

ノート@QueueBinding注釈の3つのプロパティ:

  • 値:キューを宣言するための@Queue注釈は、値は自動削除は、キューが自動的に消費者が後に削除されていないかどうかを示し、耐久性はキューが永続的であるかどうかを示し、QUEUENAMEです
  • 為替:@Exchange注釈は交換、タイプ指定されたメッセージの配信戦略を宣言するために、我々は道トピックにここにあります
  • キー:トピックよう​​に、これは我々がroutingKeyを知っているものです

上記は、キューの中のジェスチャーの使用は存在しないが、それは複雑ではないようです

3.ケース3:ああ

前のRabbitMQの学習プロセスのコア知識では、データの一貫性を確保するために、メッセージの確認応答メカニズムがあることを知っているだろう。

我々は、デフォルトのACKモードを変更したい場合は以下のようにACKここでは主に消費者側のために、(NOACK、自動、手動)、処理することができます

/**
 * 需要手动ack,但是不ack时
 *
 * @param data
 */
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "topic.n2", durable = "false", autoDelete = "true"),
        exchange = @Exchange(value = "topic.e", type = ExchangeTypes.TOPIC), key = "r"), ackMode = "MANUAL")
public void consumerNoAck(String data) {
    // 要求手动ack,这里不ack,会怎样?
    System.out.println("consumerNoAck: " + data);
}

上記の実装が提供さ、比較的簡単でackMode=MANUAL、手動ACK

しかし、私たちの実装は、何の場所が存在しないことをしてくださいノートでは、これはACKでない場合と同じに相当し、手動ACKが、ACK、後のテストでは、それは見ることができますされていない反映して、データがされていることがわかりますunacked。このコラムUnackedの数が制限値を超えた場合、それは新しいデータを消費しません。

4. CASE4:マニュアルACK

上記の選択ACKの道が、それでもステップACKロジックが欠落し、満たされた方法での外観をしましょう

/**
 * 手动ack
 *
 * @param data
 * @param deliveryTag
 * @param channel
 * @throws IOException
 */
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "topic.n3", durable = "false", autoDelete = "true"),
        exchange = @Exchange(value = "topic.e", type = ExchangeTypes.TOPIC), key = "r"), ackMode = "MANUAL")
public void consumerDoAck(String data, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel)
        throws IOException {
    System.out.println("consumerDoAck: " + data);

    if (data.contains("success")) {
        // RabbitMQ的ack机制中,第二个参数返回true,表示需要将这条消息投递给其他的消费者重新消费
        channel.basicAck(deliveryTag, false);
    } else {
        // 第三个参数true,表示这个消息会重新进入队列
        channel.basicNack(deliveryTag, false, true);
    }
}

この方法は、さらに2つの引数を追加することに注意

  • deliveryTag一意のメッセージは、MQ ACK / NAKを区別するためにされたメッセージを、識別に相当
  • channel:MQおよび消費者との間の導管、ACK / NAKを介して

我々は正しい消費、呼び出すことによって、ときにbasicAckメソッドをすることができ

// RabbitMQ的ack机制中,第二个参数返回true,表示需要将这条消息投递给其他的消费者重新消费
channel.basicAck(deliveryTag, false);

私たちが消費するときに失敗し、メッセージが再消費を待って、待ち行列に再挿入する必要があり、使用することができます basicNack

// 第三个参数true,表示这个消息会重新进入队列
channel.basicNack(deliveryTag, false, true);

5. CASE5:同時消費

ニュースの多くは、Hangchihangchiの消費支出は遅すぎる場合には、私のマシンのパフォーマンスやレバレッジ、このとき私は同じ時間に相当並行消費量を、願っていますより多くの消費者は、プロセスデータにあります

同時消費をサポートするには、次の設定が可能

@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "topic.n4", durable = "false", autoDelete = "true"),
        exchange = @Exchange(value = "topic.e", type = ExchangeTypes.TOPIC), key = "r"), concurrency = "4")
public void multiConsumer(String data) {
    System.out.println("multiConsumer: " + data);
}

ノート注釈してくださいconcurrency = "4"固定4、消費者であるプロパティを、。

上記割当この方法に加えて、あるm-nフォーマットは、m個の平行な消費者を表し、nはそこまでであってもよいです

(追加説明:このパラメータは、それを説明しSimpleMessageListenerContainer、次の記事の場面でそれを紹介しますDirectMessageListenerContainer差)

6.テスト

フロント予約を通じてインターフェイスをメッセージング、我々はブラウザを要求します。 http://localhost:8080/publish?exchange=topic.e&routing=r&data=wahaha

消費

その後、出力を見て、5つの消費者は、消費者がメッセージを受信して​​いることを特にNAKイニシアチブを受けています。

(ASので、アプリケーションを再起動し、次のテストを開始し、ログを印刷されています)

その後、要求コマンド上記のケースがあるかどうか、成功メッセージ、ACK真マニュアルの検証を送信します。 http://localhost:8080/publish?exchange=topic.e&routing=r&data=successMsg

次に、キューのないACKを見ていない、未確認の報道がありました

II。その他

ボーエンシリーズ

ソースプロジェクト

1. グレーブログ:https://liuyueyi.github.io/hexblog

灰色の個人ブログ、ブログ内のすべての研究と仕事を記録し、周りに行くことを歓迎

2.ステートメント

本は良いとして、上記、により制限され、個人能力に、純粋な言葉の一つであるされていない、すべてを信じて、それは避けられない欠落やミス、などのバグを見つけたり、より良い提案を歓迎批判と寛大な感謝されていがあります

3.スキャン懸念

灰色のブログ

QRコード

公開された206元の記事 ウォン称賛57 ビュー160 000 +

おすすめ

転載: blog.csdn.net/liuyueyi25/article/details/105207235