もちろん、あなたがSpringBoot環境の消費者を持っている必要がでのRabbitMQメッセージング姿勢を導入する前に、消費が持つ、比較的簡単であると言うことができる、送信がされているので、@RabbitListener
あなたは基本的にビジネスの開発ニーズの90%以上を満たすことができ、注釈
ここでは、見て@RabbitListener
のジェスチャーの最も一般的な用途
I. 配置
SpringBootは、最初に、後続のプレゼンテーションのためのプロジェクトを作成します
- springbootバージョン
2.2.1.RELEASE
- RabbitMQのバージョン
3.7.5
(インストールのチュートリアルを参照してください:[MQシリーズ] springboot + RabbitMQの初体験)
依存コンフィギュレーション・ファイルの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。その他
ボーエンシリーズ
- [MQシリーズ] springboot + RabbitMQの初めての経験
- [MQシリーズ] RabbitMQのコア知識の概要
- [MQ]は基本的なメッセージのSprigBoot + RabbitMQのシリーズは、ジェスチャを使用して送信しました
- [] RabbitMQのMQシリーズメッセージ確認/取引メカニズムジェスチャーを使用して
ソースプロジェクト
- プロジェクト:https://github.com/liuyueyi/spring-boot-demo
- 出典:https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/302-rabbitmq-consumer
1. グレーブログ:https://liuyueyi.github.io/hexblog
灰色の個人ブログ、ブログ内のすべての研究と仕事を記録し、周りに行くことを歓迎
2.ステートメント
本は良いとして、上記、により制限され、個人能力に、純粋な言葉の一つであるされていない、すべてを信じて、それは避けられない欠落やミス、などのバグを見つけたり、より良い提案を歓迎批判と寛大な感謝されていがあります
- マイクロブログ住所:少しグレーブログ
- QQ:グレー/ 3302797840
3.スキャン懸念
灰色のブログ