RocketMQ の基本入門 ---パート 1

ここに画像の説明を挿入します

1. RocketMQ の概要

まずはつまらない話をしましょう

RocketMQ は、純粋な Java の分散キュー モデルのオープン ソース メッセージ ミドルウェアとして、トランザクション メッセージ、順次メッセージ、バッチ メッセージ、遅延メッセージ、メッセージ トレースバックなどをサポートします。

  • 以前は MetaQ として知られていましたが、Alibaba によって開発されたキュー モデルのメッセージ ミドルウェアです。その後、Apache Foundation にオープンソース化され、Apache のトップ オープン ソース プロジェクトになりました。高性能、高信頼性、高リアルタイム性、分散性という特徴があります。 。
  • RocketMQ は、高可用性分散クラスター技術に基づいてアリババ グループが独自に開発し、クラウドで正式に商用化されたプロフェッショナル メッセージ ミドルウェアであり、分散アプリケーション システムに非同期デカップリングおよびピークシェービング機能を提供するだけでなく、分散アプリケーション システムに必要な機能も備えています。インターネット アプリケーション: 大量のメッセージの蓄積、高スループット、信頼性の高い再試行、およびアリババが必要とするその他の機能は、ダブル 11 中に使用される中核製品です。
  • RocketMQ はもともと Alibaba によって内部的に使用され、2017 年に Apache Foundation に提出され、Apache Foundation のトップ オープン ソース プロジェクトになりました。

1.特長

  • パブリッシュ/サブスクライブおよびポイントツーポイントメッセージング モデルをサポート
  • 信頼性の高い FIFOキュー内の厳密な注文配信
  • プルモードプッシュモードをサポート

実際、プルとはコンシューマーが MQ からメッセージを積極的にプルすることを意味しますが、プッシュはウサギの MQ に似ており、MQ がメッセージをコンシューマーにプッシュします。しかし、RocketMQ のプッシュは実際にはプルに基づいて実装されています。
まずビジネス コードによって MQ からメッセージをプルし、次にビジネス コードによって特定のアプリケーション/コンシューマにプッシュします。実際、最下層はプルモードです

  • 単一のキューには数百万のメッセージを蓄積する機能があります (RocketMQ は数億のメッセージを蓄積する機能を提供します。重要な点は、数十億のメッセージを処理した後も低い書き込みレイテンシを維持することです)。
  • JMS、MQTT などの複数のプロトコルをサポートします。
  • 分散型で可用性の高い展開アーキテクチャは、1 つのメッセージ配信のセマンティクスを満たします。
  • 分離とクラウド クラスターの展開用の Docker イメージを提供する
  • 構成、メトリクス、健全性のための機能豊富なダッシュボードを提供します

2. 利点

現在、主流の MQ は主に RocketMQ、kafka、RabbitMQ であり、その主な利点は次のとおりです。

  • トランザクション メッセージのサポート (メッセージ送信と DB 操作は双方の最終的な整合性を維持します。RabbitMQ と Kafka はサポートしません)
  • RocketMQ と組み合わせた複数システム間の最終的なデータ整合性をサポート (マルチパーティ トランザクション、ツーパーティ トランザクションが前提条件)
  • 18 レベルの遅延メッセージをサポート (1 秒、3 秒、5 秒、20 秒、...2 時間。カスタマイズはサポートされていません)
  • 指定された時刻および時間間隔での失敗したメッセージの再送信をサポートします (Kafka はこれをサポートしていません。RabbitMQ は手動で確認する必要があります)。
  • 不必要な送信を削減するためにブローカー側のタグ フィルタリングをサポートします (RabbitMQ と Kafka はサポートしていません)。
  • 繰り返しの消費をサポート (RabbitMQ はサポートしませんが、Kafka はサポートします)

2. RocketMQ の基本概念

RocketMQ には主に、NameServer、Broker、Producer、Consumer の 4 つのコア コンポーネントがあります。

ここに画像の説明を挿入します

1.ネームサーバー

ネーム サーバーは、ノード間で情報を同期せずにクラスターに展開できる、ほぼステートレスなノードです。

NameServer は RocketMQ 全体の「頭脳」であり、RocketMQ のサービス登録センターであるため、RocketMQ は最初に NameServer を起動してから、Rocket のブローカーを起動する必要があります。

1. ネームサーバーの役割

ネームサーバー (NameServer) は、ブローカー関連のメタ情報を保存し、プロデューサーとコンシューマーのブローカー情報を検索するために使用されます。

NameServer は、ほぼステートレスになるように設計されており、水平方向に拡張できます。ノード間の通信はなく、複数のマシンを展開することによって、それ自体をクラスターとしてマークします。

各ブローカーは、起動時にネームサーバーに登録します。プロデューサーは、メッセージをネームサーバーに送信する前に、トピックに基づいてブローカーのルーティング情報を取得します。コンシューマーもトピックのルーティング情報を定期的に取得します。したがって、機能の観点からは、 RocketMQ の初期バージョンでは ZooKeeper が使用されていましたが、後に NameServer を独自に実装するように変更されたと言われています。

2.zkとの違い

ネーム サーバーと ZooKeeper の機能はほぼ同じです。マクロの観点から見ると、ネーム サーバーは実行中のデータを保存するだけで、ほとんど機能しません。ネーム サーバーは相互接続されていないため、ブローカーがすべてのネーム サーバーに接続して実行する必要があります。データ実行中のデータの一貫性を確保するには、変更を各ネーム サーバーに送信する必要があります (この一貫性は確かに少し弱いです)。これによりネーム サーバーは非常に軽量になりますが、ブローカー側はさらに多くのことを行う必要があります。

ZooKeeper に関しては、ブローカーはいずれかのマシンに接続するだけで済み、実行中のデータの分散と整合性はすべて ZooKeeper によって完了します。

3. 高可用性の保証

ブローカーは起動時にすべてのネームサーバー (主にサーバー アドレスなど) に登録します。メッセージを送信する前に、プロデューサーはネームサーバー (コンシューマーと同じ) からブローカー サーバーのアドレス リストを取得し、そのリストに基づいてメッセージを送信するサーバーをリストから選択します。負荷分散アルゴリズム。送信

NameServer は各 Broker サービスとの接続を長時間維持し、10 秒ごとに Broker が生きているかどうかをチェックし、Broker がダウンしていることを検出するとルーティング レジストリから削除することで、RocketMQ の高可用性を実現します。

2.ブローカー

メッセージ サーバー (ブローカー) はメッセージ ストレージ センターです。その主な機能は、プロデューサーからメッセージを受信して​​保存することです。コンシューマはここからメッセージを取得します。また、ユーザー グループ、消費進行状況のオフセット、キュー情報など、メッセージに関連するメタデータも保存します。 . 配置構造図からわかるように、Broker には Master と Slave の 2 つのタイプがあり、Master は書き込みと読み取りの両方が可能ですが、Slave は書き込みができず読み取りのみが可能です。

1 導入方法

ブローカーの導入は比較的複雑です。ブローカーはマスターとスレーブに分かれています。1 つのマスターは複数のスレーブに対応できますが、1 つのスレーブは 1 つのマスターにのみ対応します。マスターとスレーブ間の対応関係は、同じブローカー名と異なるブローカーを指定することによって定義されます。 Id. BrokerId 0 はマスターを意味し、0 以外はスレーブを意味し、マスターは複数のデプロイも可能

物理構造の観点から見ると、Broker クラスターの展開方法には 4 つあります。単一マスター、複数マスター、複数マスターと複数スレーブ (同期ディスク フラッシュ)、複数マスターと複数スレーブ (非同期ディスク フラッシュ) です。

  • シングル マスター: この方法では、ブローカーが再起動またはダウンすると、サービス全体が利用できなくなります。この方法は危険であるため、オンライン環境ではお勧めできません。
  • マルチマスター: すべてのメッセージ サーバーはスレーブなしでマスターです。この方法の利点は、構成が簡単で、単一マスターのダウンタイムや再起動のメンテナンスがアプリケーションに影響を与えないことです。欠点は、メッセージ サーバーのダウンタイム中に、単一のマシンの場合、マシン上の未消費のメッセージ。マシンが復元されるまでサブスクライブできず、メッセージのリアルタイム性が影響を受けます。
  • 複数のマスターと複数のスレーブ (非同期レプリケーション) : 各マスターはスレーブで構成されているため、マスターとスレーブの複数のペアが存在します。メッセージは非同期で複製されます。マスターとスレーブの間でミリ秒のメッセージ遅延があります。この方法の利点は次のとおりです。失われるメッセージはほとんどないということです。メッセージのリアルタイム性は影響を受けません。マスターがダウンした後も、コンシューマはスレーブから消費を続けることができます。中間プロセスはユーザー アプリケーションに対して透過的であり、手動介入。パフォーマンスはマルチマスター方式とほぼ同じです。欠点は、マスターがダウンすると、ディスク破損の場合に非常に少量のメッセージが失われることです。
  • マルチマスターとマルチスレーブ (同期レプリケーション) : 各マスターはスレーブで構成されているため、マスターとスレーブのペアが複数あります。メッセージは同期的に複製されます。マスターとスレーブの書き込みが成功した場合にのみ成功が返されます。この方法では、単一のデータとサービスが存在しないという点が挙げられます。問題は、マスターがダウンしているときにメッセージの遅延がなく、サービスとデータの可用性が非常に高いことです。欠点は、パフォーマンスがこの方法よりわずかに低いことです。非同期レプリケーション方式のため、メッセージ送信の遅延が若干長くなります。

3. 高可用性の保証

各ブローカーは、ネーム サーバー クラスター内のすべてのノードとの長い接続を確立し、定期的に (30 秒ごとに) すべてのネーム サーバーにトピック情報を登録し、ネーム サーバーは、存続しているすべてのブローカーの接続を定期的に (10 秒ごとに) スキャンします。 2 分 ハートビートが受信されない場合、ネーム サーバーはブローカーから切断されます。

4.プロデューサー

プロデューサー: メッセージ パブリッシャーとも呼ばれ、メッセージを作成してトピックに送信する責任を負います。

プロデューサーは、ビジネス アプリケーション システムによって生成されたメッセージをブローカーに送信します。RocketMQ は、同期、非同期、一方向の複数の送信モードを提供します。

1.同期送信:同期送信とは、メッセージ送信者がデータを送信した後、受信者からの応答を受信して​​から次のデータ パケットを送信することを意味し、一般に重要な通知メールやマーケティング テキスト メッセージなどの重要な通知メッセージに使用されます。 。

2.非同期伝送:非同期伝送とは、送信側がデータを送信した後、受信側の応答を待たずに次のデータ パケットを送信することを意味し、一般的に通信に時間がかかるビジネス シーンで使用されます。ビデオがアップロードされると、トランスコーディング サービスを開始するように通知されます。コールバックをリッスンして送信結果を取得する

3.一方向送信:一方向送信は、サーバーの応答を待たず、コールバック関数のトリガーも行わずにメッセージを送信することのみを担当します。非常に短時間かかるものの、高い信頼性を必要としない一部のシナリオに適しています。ログ収集として。これは、kafka の送信して忘れるのと似ています。

4.プロデューサー グループ:プロデューサー グループ (プロデューサー グループ) は、あるタイプのプロデューサーの集合です。このタイプのプロデューサーは、通常、あるタイプのメッセージを送信し、一貫したロジックを送信するため、これらのプロデューサーをグループ化します。デプロイメント構造の観点から、プロデューサーはプロデューサー グループ名を渡して、それ自体をクラスターとしてマークします。

5.高可用性の保証:

  • プロデューサー グループ (プロデューサー グループ) は、プロデューサーのタイプのコレクションです。通常、このタイプのプロデューサーは、あるタイプのメッセージを送信し、論理的に一貫した送信を行うため、これらのプロデューサーはグループ化されます。デプロイメント構造から、プロデューサーは、自分自身をその名前でマークします。プロデューサー グループはクラスターです
  • プロデューサーは、ネーム サーバーからすべてのトピック キューの最新ステータスを 30 秒ごとに取得します (ClientConfig の pollNameServerInterval によって)。つまり、ブローカーが利用できない場合、プロデューサーはそれを最大 30 秒間認識でき、この間にブローカーに送信されたすべてのメッセージが表示されます。期間は失敗します。
  • プロデューサーは、関連付けられているすべてのブローカーに 30 秒ごとにハートビートを送信し (ClientConfig の heartbeatBrokerInterval によって決定)、ブローカーは、残っているすべての接続を 10 秒ごとにスキャンします。ブローカーが 2 分以内にハートビート データを受信しない場合、プロデューサーとの接続が閉じられます。

5.消費者

メッセージ サブスクライバとも呼ばれ、トピックからのメッセージを受信して​​消費する責任があります。

コンシューマはブローカーから情報を取得し、それをアプリケーションに入力します。ユーザー アプリケーションの観点から見ると、次の 2 種類のコンシューマが提供されます。

  • Pull : プル コンシューマーはブローカーから情報を積極的にプルします。メッセージがバッチでプルされる限り、ユーザー アプリケーションは消費プロセスを開始します。
  • Push : プッシュ タイプのコンシューマは、メッセージの取得、消費の進行状況、その他の内部メンテナンス タスクをカプセル化し、メッセージがエンド ユーザーに到着したときに実行されるコールバック インターフェイスを残します。

1. 消費者グループ:

  • Consumer Group (Consumer Group) は、Consumer のコレクションの名前です。このタイプの Consumer は、通常、同じタイプのメッセージを消費し、同じ消費ロジックを持つため、これらの Consumer はグループ化されます。Consumer Group は、Producer Group と似ているという点で、グループ化と名前付け、グループ化は非常に微妙な概念設計であり、RocketMQ はこのグループ化メカニズムを通じて自然なメッセージ負荷分散を実現します。
  • メッセージを消費するとき、メッセージはコンシューマ グループを通じて複数のコンシューマ サーバー インスタンスに配信されます。たとえば、トピックに 9 つのメッセージがあり、コンシューマ グループの 1 つに 3 つのインスタンス (3 つのプロセスまたは 3 つのマシン) がある場合、各インスタンスには 3 つのメッセージが含まれます。平等に共有できるということは、マシンを追加することで水平方向の拡張も容易に実現できることを意味します。プロデューサープロデューサープロデューサープロデューサー

2. 高可用性の保証:

  • コンシューマは、ネーム サーバー クラスタ内のノード (ランダムに選択) の 1 つとの長い接続を確立し、ネーム サーバーからトピック ルーティング情報を定期的に取得し、トピック サービスを提供するマスターおよびスレーブとの長い接続を確立し、ハートビートを定期的に送信します。マスターとスレーブ コンシューマー マスターまたはスレーブからのメッセージをサブスクライブできます サブスクリプション ルールは、ブローカーの設定によって決まります。
  • Consumer は、トピックの最新のキュー ステータスを 30 秒ごとにネーム サーバーから取得します。つまり、Broker が利用できない場合、Consumer がそれを認識するまでに最大 30 秒かかります。
  • Consumer は、関連するすべてのブローカーに 30 秒ごとにハートビートを送信します (ClientConfig の heartbeatBrokerInterval によって決定されます)。Broker は、残っているすべての接続を 10 秒ごとにスキャンします。接続が 2 分以内にハートビート データを送信しない場合、接続は閉じられます。すべてのコンシューマが通知を発行し、グループ内のコンシューマがキューを再配布して消費を継続します。
  • Consumer はマスターのダウンタイムを通知されると、スレーブに頼って消費します。スレーブはマスターのメッセージが 100% 同期されていることを保証できないため、少量のメッセージが失われます。ただし、マスターが回復すると、非同期メッセージは最終的に消費されます。
  • コンシューマ キューは、コンシューマが接続された後 (または以前に接続されたことがある場合) に作成されます。ネイティブ コンシューマ識別子を {IP}@{consumer group} から {IP}@{consumer group}{topic }{tag} に拡張します。(たとえば、xxx.xxx.xxx.xxx@mqtest_Producer-group_2m2sTest_tag-zyk)、異なる要素は異なるコンシューマとみなされ、各コンシューマは独自の消費リストを持ちます (デフォルトは、ブローカー ペアの数 * 数値です)ブローカーの)、新しくマウントされたコンシューマ ペアにはコミットログ内のすべてのデータが含まれます

6. 運用プロセス

ここに画像の説明を挿入します

  1. NameServer が最初に起動します
  2. ブローカーは起動時に NameServer に登録します
  3. 特定のトピックに関するメッセージを送信する前に、プロデューサーはまず NamerServer からブローカー サーバーのアドレス リスト (おそらくクラスター) を取得し、次に、負荷分散アルゴリズムに基づいてメッセージを送信するブローカーをリストから選択します。
  4. NameServer は、各ブローカー サーバーとの長い接続を維持し、ブローカーが生きているかどうかを 10 秒ごとにチェックします。ブローカーがダウンしていることを検出すると (ハートビート メカニズムを使用し、検出が 120 秒を超えた場合)、ルーティング レジストリから削除されます。 。
  5. コンシューマーは、トピックのメッセージをサブスクライブする前に、NamerServer からブローカー サーバーのアドレス リスト (クラスターの場合もあります) を取得しますが、コンシューマーは、ブローカーからのメッセージをサブスクライブすることを選択します。サブスクリプション ルールは、ブローカーの構成によって決まります。

7.用語の説明

  1. メッセージ: メッセージは、送信される情報です。メッセージにはトピックが必要です。トピックは、レターの郵送先アドレスとみなすことができます。メッセージには、オプションのタグと金額も含めることができます。キーと値のペアは、次のとおりです。 、ビジネス キーを設定し、ブローカー上でこのメッセージを検索して開発中に問題を見つけるために使用できます。
  2. トピック:

トピックはメッセージのタイプとみなすことができ、これはメッセージの第 1 レベルのタイプです。

たとえば、電子商取引システムは、トランザクション メッセージ、物流メッセージなどに分類できます。メッセージにはトピックが必要です。トピックと生産者および消費者の関係は非常に緩やかです。トピックには 0、1、または複数のメッセージを含めることができます。プロデューサはメッセージを送信しますが、プロデューサは同時に異なるトピックにメッセージを送信することもでき、トピックは 0、1、または複数のコンシューマによってサブスクライブすることもできます

  1. タグ:

タグは、ユーザーにさらなる柔軟性を提供するために使用される第 2 レベルのメッセージであるサブトピックとして見ることができます。

タグを使用すると、同じビジネス モジュール内の異なる目的を持つメッセージを、同じトピックで異なるタグで識別できます。たとえば、トランザクション メッセージは、トランザクション作成メッセージ、トランザクション完了メッセージなどに分割できます。メッセージにはタグは必要ありません。タグは、コードをクリーンで一貫性のあるものに維持するのに役立ち、RocketMQ が提供するクエリ システムにも役立ちます。

  1. メッセージキュー:

メッセージ キュー (メッセージ キュー)。トピックは 1 つ以上のサブトピック、つまりメッセージ キューに分割されます。

トピックの下に複数のメッセージ キューを設定できます。メッセージを送信すると、メッセージのトピックが実行されます。RocketMQ は、トピックの下にあるすべてのキューをポーリングしてメッセージを送信します。次の図は、ブローカーの内部メッセージの状況を示しています。
ここに画像の説明を挿入します

  1. メッセージ消費モデル:

メッセージ消費モードには、クラスター消費 (クラスタリング) とブロードキャスト消費 (ブロードキャスト) の 2 つがあります。

デフォルトはクラスタ消費です。このモードでは、コンシューマ・クラスタはトピックの複数のキューを共同で消費します。キューは1つのコンシューマによってのみ消費されます。コンシューマが死亡すると、グループ内の他のコンシューマが引き継ぎます。コンシューマの消費は継続します。

ブロードキャスト消費メッセージは、消費のためにコンシューマ グループ内のすべてのコンシューマに送信されます。

  1. メッセージシーケンス:

メッセージの順序には、順次消費 (Orderly) と並列消費 (Concurrently) の 2 種類があります。

順次消費とは、メッセージ消費の順序が、各メッセージ キューのプロデューサーによって送信された順序と一致していることを意味します。したがって、グローバルな順序が必須であるシナリオを扱っている場合は、使用されるトピックにメッセージが 1 つだけ含まれていることを確認する必要があります。キュー。並列消費はメッセージの順序を保証しなくなりました。消費される並列処理の最大量は、各コンシューマ クライアントによって指定されたスレッド プールによって制限されます

3. デザインコンセプト

RocketMQ の設計は、トピック パブリッシングおよびサブスクリプション モデルに基づいています。そのコア機能には、メッセージ送信、メッセージ ストレージ (ブローカー)、およびメッセージ消費が含まれます。全体的な設計は、シンプルさとパフォーマンスを第一に追求しており、主に次の 3 つの側面に反映されています。

1. NameServer の設計は非常にシンプルです。RocketMQ は登録センターとして業界で一般的に使用されている Zookeeper を放棄しますが、トピック ルーティング情報はクラスター間の強い一貫性を維持する必要がなく、究極の一貫性を追求するため、メタデータの管理に自社開発の NameServer を使用します。 . 、分レベルの不一致を許容できるため、RocketMQ の NameServer クラスターは相互に通信しなくなり、設計の複雑さが大幅に軽減され、ネットワーク要件が軽減され、パフォーマンスが向上します。

2. 効率的な IO ストレージ メカニズム:

  • RocketMQ はメッセージ送信の高スループットを追求しており、RocketMQ のメッセージ保存ファイルはファイルグループの概念で設計されており、グループ内の 1 つのファイルのサイズが固定されているため、メモリマッピング機構の導入が容易です。
  • すべてのトピックのメッセージ ストレージは、書き込みパフォーマンスを向上させるためにシーケンシャル書き込みに基づいており、同時に、メッセージ消費とメッセージ検索のバランスを取るために、メッセージ消費キュー ファイルとインデックス ファイルが導入されています。

3. 既存の設計上の欠陥を許容する

特定のタスクを RocketMQ ユーザーに適切に委任すると、メッセージ ミドルウェアの実装者が問題に遭遇することがよくあります。

メッセージがメッセージ コンシューマによって消費され、一度だけ消費されるようにするにはどうすればよいでしょうか? RocketMQ の設計者が提供した解決策は、この問題を解決することではなく、次善の策に落ち着いて、メッセージがメッセージ コンシューマによってのみ消費されるようにすることです。ただし、メッセージを繰り返し消費できるように設計されているため、メッセージ ミドルウェアのコアが大幅に簡素化され、メッセージ送信の高可用性を非常にシンプルかつ効率的に実現できます。メッセージの重複の問題は、コンシューマによって解決されます。メッセージを消費するときの冪等性。

4. RocketMQ アーキテクチャ

ここに画像の説明を挿入します

1ネームサーバークラスター: 軽量のサービス ディスカバリとルーティングを提供します。各 NameServer は完全なルーティング情報を記録し、対応する読み取りおよび書き込みサービスを提供し、迅速なストレージ拡張をサポートします。他の一部のオープン ソース ミドルウェアは、ZooKeeper を使用してサービス ディスカバリとルーティング機能を実装しています (Apache Kafka など)。

NameServer は、主に 2 つの機能を含む完全な機能を持つサーバーです:
1. ブローカー管理、ブローカー クラスターから登録リクエストを受け取り、ブローカーが生きているかどうかを検出するハートビート メカニズムを提供します 2. ルーティング管理 各ネームサーバーは、関連するすべての
ブローカー クラスターを保持しますおよびクライアントリクエスト キュールーティング情報

2.ブローカークラスター: 軽量のトピックおよびキュー メカニズムを提供することでメッセージ ストレージを処理し、フォールト トレラント メカニズムを含むプッシュ モデルとプル モデルの両方をサポートします従来のメッセージング システムには欠けていたディザスタ リカバリ、豊富なメトリック統計、およびアラート メカニズムを提供することに加えて、強力なピーク フィルと数千億のメッセージを元の時系列順に蓄積する機能を提供します。

Broker にはいくつかの重要なサブモジュールがあります。

  • リモート処理モジュール、ブローカー入口、クライアントからのリクエストを処理します
  • クライアント管理、クライアント (メッセージ プロデューサおよびコンシューマを含む) を管理し、コンシューマ トピックのサブスクリプションを維持します。
  • ストレージ サービス。物理ハード ディスクにメッセージを保存およびクエリするためのシンプルな API を提供します。
  • HA サービスは、マスター ブローカーとスレーブ ブローカー間のデータ同期を提供します。
  • 指定されたキーによってメッセージのインデックスを作成し、高速なメッセージ クエリを提供するインデックス サービス。

3.プロデューサークラスター: メッセージ プロデューサーは分散デプロイメントをサポートしており、分散プロデューサーはさまざまなロード バランシング モードを通じてブローカー クラスターにメッセージを送信します。

4.コンシューマクラスタ: メッセージ コンシューマーは、プッシュ モデルとプル モデルの分散展開もサポートし、クラスター消費とメッセージ ブロードキャストもサポートし、ほとんどのコンシューマーのニーズを満たすことができるリアルタイムのメッセージ サブスクリプション メカニズムを提供します。

アーキテクチャ図でクラスターがどのように相互作用するかを説明します。

  • Broker Master と Broker Slave はマスター/スレーブ構造であり、データ同期 Data Sync を実行します。
  • 各ブローカーは、ネームサーバー クラスター内のすべてのノードとの長期接続を確立し、トピック情報をすべてのネームサーバーに定期的に登録します。
  • プロデューサーは、ネームサーバー クラスター内のノードの 1 つと (ランダムに) 長い接続を確立し、ネームサーバーからトピック ルーティング情報を定期的に取得し、トピック サービスを提供するブローカー マスターとの長い接続を確立し、定期的にハートビートをブローカーに送信します。
  • プロデューサーはブローカー マスターにメッセージを送信することしかできませんが、コンシューマーはトピック サービスを提供するマスターおよびスレーブとの長期接続も確立し、マスターまたはスレーブからのメッセージをサブスクライブできます。

5. 設計目標

1.アーキテクチャパターン

RocketMQ は、ほとんどのメッセージ ミドルウェアと同様に、パブリッシュ/サブスクライブ モデルを採用しており、基本的な参加コンポーネントには主に、メッセージ送信者、メッセージ サーバー (メッセージ ストレージ)、メッセージ消費、およびルート検出が含まれます。

1.連続メッセージ: 厳密に順番に発行および消費されるメッセージ タイプです。メッセージの発行と消費が順番に実行される必要があります。RocketMQ は、メッセージが順番に並んでいることを厳密に保証できます。

  • RocketMQ はメッセージの順序を厳密に保証できますが、この順序はグローバル順序ではなく、パーティション (キュー) の順序です。グローバル順序は 1 つのパーティションのみですが、同じキュー内では、RocketMQ は確かに FIFO を保証できます。

2.メッセージのフィルタリング:メッセージ フィルタリングは、メッセージを消費するときに、メッセージ コンシューマが同じトピックのルールに従って興味のあるメッセージのみを消費できることを意味します。RocketMQ メッセージ フィルタリングは、サーバー側とコンシューマ側でメッセージ フィルタリング メカニズムをサポートします。

  1. メッセージはブローカー側でフィルタリングされ、ブローカーはメッセージ コンシューマが関心のあるメッセージのみをメッセージ コンシューマに送信します。
  2. メッセージはメッセージ コンシューマ側でフィルタリングされ、メッセージ フィルタリング方法はメッセージ コンシューマによって完全にカスタマイズされますが、欠点は、多くの無駄なメッセージがブローカからコンシューマ側に送信されることです。

3.メッセージストレージ: メッセージ ミドルウェアのコア実装はメッセージのストレージです。メッセージ ストレージについては、通常、次の 2 つの側面を考慮する必要があります。

  • メッセージ蓄積機能とメッセージストレージパフォーマンス RocketMQ はメッセージストレージの高いパフォーマンスを追求し、メモリマッピングメカニズムを導入しています すべてのトピックのメッセージは同じファイルに順番に保存されます 同時に、メッセージが無制限に蓄積されるのを避けるためメッセージストレージサーバー、メッセージファイルの有効期限が導入されるメカニズムとファイルストレージスペースのアラームメカニズム

2. メッセージの高可用性

通常、次の状況はメッセージの信頼性に影響します。

  1. ブローカーは正常にシャットダウンします
  2. ブローカーが異常終了する
  3. オペレーティングシステムがダウンしている
  4. マシンの電源が失われますが、電源はすぐに復旧できます
  5. マシンの電源が入らない(CPU、マザーボード、メモリ、その他の主要なデバイスが損傷している可能性があります)
  6. ディスクデバイスが破損しています

上記の状況に対応して、状況 1 ~ 4 の RocketMQ は、同期ディスク フラッシュ メカニズムではメッセージが失われないことを保証できますが、非同期ディスク フラッシュ モードでは少量のメッセージが失われます。状況 5 ~ 6 は単一点障害です。これらが発生すると、ノード上のすべてのメッセージが失われます。非同期レプリケーション メカニズムが有効になっている場合、RoketMQ は少量のメッセージのみが失われることを保証し、同期レプリケーションの使用を保証します。このメカニズムは、非常に高いメッセージ信頼性の要件を満たすことができます。

1.メッセージから消費までの低遅延: RocketMQ は、メッセージが蓄積されない場合に、ロング ポーリング モードを使用して、準リアルタイムのメッセージ プッシュ モードを実現します。

2.メッセージが 1 回消費されることを確認する: RocketMQ は、メッセージ消費確認メカニズム (ACK) を使用して、メッセージが少なくとも 1 回消費されることを保証しますが、ACK メッセージが失われる可能性などの他の理由により、RocketMQ はメッセージ消費確認メカニズム (ACK) を使用できません。メッセージが 1 回だけ消費され、繰り返し消費されるようにします。

3.トレースバック メッセージ: トレースバック メッセージは、メッセージ コンシューマによって正常に消費されたメッセージを指します。ビジネス要件により、メッセージは再度消費される必要があります。RocketMQ は時間によるトレースバック メッセージをサポートしています。時間ディメンションはミリ秒まで正確で、前方または後方にトレースします。

4.メッセージ蓄積: メッセージミドルウェアの主な機能は非同期デカップリングであり、フロントエンドのデータピークに対処し、バックエンドシステムの可用性を向上させることができなければならず、一定のメッセージ蓄積機能を備えている必要があります。ストレージはディスク ファイルを使用し (メモリ マッピング メカニズム)、物理レイアウトでは、複数の同じサイズのファイルが論理ファイル グループを形成し、無限に使用できます。RocketMQ メッセージ ストレージ ファイルはメッセージ サーバーに永続的に保存されるわけではありませんが、有効期限が設けられています。このメカニズムはデフォルトで保持されます 3 sky

5.遅延メッセージ: 遅延メッセージとは、メッセージがブローカーに送信された後、メッセージ コンシューマーによってすぐに消費できないことを意味します。消費できるようになるまで、特定の時点まで待機するか、特定の時間待機する必要があります。

  • 任意の精度でメッセージ消費のタイミングをサポートしたい場合は、メッセージ サーバー側でメッセージを並べ替える必要がありますが、これは必然的に大きなパフォーマンスの損失をもたらします。そのため、RocketMQ は任意の進行度でのタイミング メッセージをサポートせず、特定の進行状況のみをサポートします。遅延レベル。(一説には、メッセージのタイミングを任意の精度で設定するとパフォーマンスが低下するという説がありますが、Alibaba Cloud バージョンの RocketMQ にはそのような機能があり、再充電優先戦略?)

6メッセージ再試行メカニズム: メッセージ再試行とは、消費中にメッセージが異常に送信された場合、メッセージ ミドルウェアがメッセージの再配信をサポートする必要があることを意味します。RocketMQ はメッセージ再試行メカニズムをサポートします。

6. インストール

設置方法

7. 基本的な使い方

1. 座標の導入: RocketMQ クライアント アクセス サポートの追加 特定のバージョンは、インストールされている RocketMQ バージョンと一致する可能性があります。

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.7.1</version>
</dependency>

2.プロデューサーコード

public class Producer {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 创建一个消息生产者,并设置一个消息生产者组
        DefaultMQProducer producer = new DefaultMQProducer("niwei_producer_group");
        // 指定 NameServer 地址
        producer.setNamesrvAddr("IP:9876");
        // 初始化 Producer,整个应用生命周期内只需要初始化一次
        producer.start();
        for (int i = 0; i < 100; i++) {
    
    
            // 创建一条消息对象,指定其主题、标签和消息内容
              Message msg = new Message(
                    "topic_rocket_example" // 消息主题名,
                    "TagA" // 消息标签,
                    ("Hello Java demo RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) // 消息内容
            );
            // 发送消息并返回结果
            SendResult sendResult = producer.send(msg);
            System.out.printf("%s%n", sendResult);
        }
        // 一旦生产者实例不再被使用则将其关闭,包括清理资源,关闭网络连接等
        producer.shutdown();
    }
}

この例では、DefaultMQProducer クラスを使用してメッセージ プロデューサーが作成されます。通常、アプリケーションは DefaultMQProducer オブジェクトを作成するため、プロデューサー オブジェクトは一般にアプリケーションによって維持され、グローバル オブジェクトまたはシングルトンとして設定できます。このタイプのコンストラクタのパラメータProducerGroupは、メッセージ プロデューサー グループの名前です。プロデューサーとコンシューマの両方がGroupNameを指定する必要があり、名前の一意性が保証されている必要があります。ProducerGroupは、通常のメッセージを送信する場合にはほとんど影響しません。

次に、NameServer アドレスを指定し、初期化のために start メソッドを呼び出します。start メソッドを呼び出す必要があるのは、アプリケーションのライフ サイクル全体で 1 回だけです。

初期化が完了したら、send メソッドを呼び出してメッセージを送信します。この例では、送信するために 100 個の同一のメッセージが単純に構築されています。実際、Producer オブジェクトは、複数のトピックと複数のタグ、およびメッセージのタグを含むメッセージを送信できます。オブジェクトは空であっても構いません。send メソッドは同期呼び出しであり、例外がスローされない限り成功します。

最後に、アプリケーションが終了すると、shutdown メソッドを呼び出してリソースをクリーンアップし、ネットワーク接続を閉じ、サーバーからログアウトします。通常は、アプリケーションが JBOSS やコンテナーの終了フックで shutdown メソッドを呼び出すことをお勧めします。トムキャット。

3. メッセージコンシューマ

public class Consumer {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 创建一个消息消费者,并设置一个消息消费者组
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("niwei_consumer_group");
        // 指定 NameServer 地址
        consumer.setNamesrvAddr("IP:9876");
        // 设置 Consumer 第一次启动时从队列头部开始消费还是队列尾部开始消费
       consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        // 订阅指定 Topic 下的所有消息
       consumer.subscribe("topic_rocket_example", "*");
        // 注册消息监听器
       consumer.registerMessageListener(new MessageListenerConcurrently() {
    
    
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext context) {
    
    
                // 默认 list 里只有一条消息,可以通过设置参数setConsumeMessageBatchMaxSize()来批量接收消息
                if (list != null) {
    
    
                    for (MessageExt ext : list) {
    
    
                        try {
    
    
                            System.out.println(new Date() + new String(ext.getBody(), "UTF-8"));
                        } catch (UnsupportedEncodingException e) {
    
    
                            e.printStackTrace();
                        }
                    }
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        // 消费者对象在使用之前必须要调用 start 初始化
        consumer.start();
        System.out.println("消息消费者已启动");
    }
}

この例では、DefaultMQPushConsumer クラスを使用してメッセージ コンシューマを作成します。アプリケーションは通常、プロデューサと同様に DefaultMQPushConsumer オブジェクトを作成します。このオブジェクトは通常、アプリケーションによって維持され、グローバル オブジェクトまたはシングルトンとして設定できます。このクラス コンストラクターの入力パラメーター ConsumerGroup はメッセージ コンシューマー グループの名前であり、名前の一意性が保証される必要があります。

次に、NameServer アドレスを指定し、コンシューマ アプリケーションが最初に起動するときにキューの先頭から消費を開始するか、キューの末尾から消費を開始するかを設定します。

次に、subscribe メソッドを呼び出して、指定されたトピックの下にあるメッセージにコンシューマ オブジェクトをサブスクライブします。このメソッドの最初のパラメータはトピック名で、2 番目のパラメータはラベル名です。この例では、トピック名の下にあるすべてのラベルのメッセージをサブスクライブします。 topic_example_java がサブスクライブされています。

最も重要なことは、メッセージを消費するメッセージ リスナーを登録することです。この例では、Consumer Push メソッドが使用されています。つまり、メッセージはリスナー コールバックを設定することによって消費されます。デフォルトのリッスン コールバック メソッドでは、メッセージは 1 つだけです。情報をリストに表示し、パラメータを設定することで一括で受け取ることができます。

最後に、初期化のために start メソッドが呼び出されます。start メソッドを呼び出す必要があるのは、アプリケーションのライフ サイクル全体で 1 回だけです。

おすすめ

転載: blog.csdn.net/weixin_44702984/article/details/131077826
おすすめ