私たちは通常、スポーツ ニュース ソフトウェアを使用し、お気に入りのチームの掲示板を購読しています。著者が関連する掲示板に記事を公開すると、関連するニュースのプッシュを受け取ることができます。
パブリッシュ-サブスクライブ (Pub/Sub) はメッセージ パラダイムであり、メッセージの送信者 (パブリッシャー、プロデューサー、プロデューサーと呼ばれます) は、メッセージを特定の受信者 (サブスクライバー、コンシューマー、コンシューマーと呼ばれます) に直接送信します。RocketMQ の基本的なメッセージ モデルは、単純な Pub/Sub モデルです。
プロデューサー: メッセージの作成を担当します。通常、ビジネス システムがメッセージの作成を担当します。メッセージ プロデューサーは、ビジネス アプリケーション システムで生成されたメッセージをブローカー サーバーに送信します。RocketMQ は、通常 (同期、非同期、一方向)、順次、遅延、バッチ、トランザクション メッセージ送信など、さまざまな送信方法を提供します。
Consumer : メッセージの消費を担当します。通常、バックグラウンド システムが非同期の消費を担当します。メッセージ コンシューマーは、ブローカー サーバーからメッセージをプルし、アプリケーションに提供します。ユーザー アプリケーションの観点からは、プッシュ消費とプル消費(プッシュ、プル消費) という 2 つの消費形式が提供されます。
トピック: メッセージのクラスのコレクションを示します。各トピックには複数のメッセージが含まれます。各メッセージは 1 つのトピックにのみ属することができます。これは、メッセージ サブスクリプションの RocketMQ の基本単位です。
RocketMQとは何ですか
RocketMQ は、2012 年に Alibaba によってオープンソース化された分散メッセージング ミドルウェアです。Apache Software Foundation に寄付され、2017 年 9 月 25 日に Apache のトップレベル プロジェクトになりました。アリババのダブルイレブンの洗礼を何度も経験し、安定した優れた性能を誇る国産ミドルウェアとして、その高性能、低遅延、高信頼性により、近年ますます多くの企業で採用されています。その主な特徴は次のとおりです。
灵活可扩展性
RocketMQ は当然分散をサポートしており、その中核となる 4 つのコンポーネント (ネーム サーバー、ブローカー、プロデューサー、コンシューマー) はそれぞれ単一障害点なしで水平に拡張できます。海量消息堆积能力
RocketMQ は、超大規模メッセージの蓄積機能を実現するためにゼロコピー原理を採用しており、1 台のマシンですでに数億のメッセージの蓄積をサポートでき、非常に多くのメッセージを蓄積した後も低い書き込みレイテンシを維持します。支持顺序消息
これにより、メッセージ コンシューマが送信された順序でメッセージを消費することが保証されます。シーケンシャルメッセージはグローバルオーダーとローカルオーダーに分けられますが、一般的にはローカルオーダー、つまりプロデューサが特定の種類のメッセージを同じキューに送信することで実現することをお勧めします。多种消息
フィルタリング方法 メッセージのフィルタリングは、サーバ側のフィルタリングとコンシューマ側のフィルタリングに分けられます。サーバーサイドのフィルタリングは、メッセージ利用者の要求に応じて行うことができ、不要なメッセージ送信を削減できるメリットがありますが、メッセージサーバーの負担が大きくなり、実装が比較的複雑になるデメリットがあります。コンシューマ側のフィルタリングは、特定のアプリケーションによって完全にカスタマイズされます。この方法はより柔軟ですが、欠点は、多くの無駄なメッセージがメッセージ コンシューマに送信されることです。支持事务消息
RocketMQ は、通常のメッセージと順次メッセージのサポートに加えて、トランザクション メッセージもサポートしており、この機能は分散トランザクションに別のソリューションを提供します。回溯消费回溯
消費とは、消費者が正常に消費したニュースを指します。ビジネス ニーズによる再消費の必要性のため、RocketMQ は時間に応じた逆方向消費をサポートしています。時間次元はミリ秒単位で正確で、前方または後方に追跡できます。
基本的なメッセージ モデル (単純な Pub/Sub モデル)
上図は、プロデューサー (Producer)、コンシューマー (Consumer)、およびメッセージ トピック (Topic) に基づく中間メッセージ送信を含む、基本的なメッセージ システム モデルです。
トピックベースのシステムでは、メッセージはトピックまたは名前付きチャネルにパブリッシュされます。コンシューマは、サブスクライブするトピックに関するすべてのメッセージを受信します。プロデューサは、サブスクライバがサブスクライブするメッセージ カテゴリを定義する責任があります。これは基本的な概念モデルですが、実際のアプリケーションでは構造はさらに複雑になります。たとえば、高い同時実行性と水平拡張をサポートするには、中間メッセージ トピックを分割する必要があり、同じトピックに複数のプロデューサーが存在し、同じ情報に複数のコンシューマーが存在し、コンシューマー間の負荷分散を実行する必要があります。
拡張メッセージモデル
上の図は、2 つのプロデューサー、2 つのメッセージ トピック、および 2 つのコンシューマー グループを含む拡張メッセージ モデルです。
メッセージ トピックを格納するプロキシ サーバー (ブローカー) は、実際の展開プロセスで対応するプロキシ サーバーです。
- RocketMQ は水平方向に拡張するために Topic を分割しており、この操作をキュー (MessageQueue) と呼びます。
- 同時消費のために、Consumer Group という概念が生まれました。
- Consumer には主に、ブロードキャスト モードとクラスター モードという 2 つの消費モードがあります (図では、最も一般的に使用されるクラスター モードを示しています)。
- 同じコンシューマ グループ内のコンシューマ インスタンスは負荷分散されています。図では、ConsumerGroupA が TopicA をサブスクライブし、TopicA が 3 つのキューに対応しています。次に、GroupA の Consumer1 が MessageQueue 0 と MessageQueue 1 からのメッセージを消費し、Consumer2 が MessageQueue2 からのメッセージを消費します。 . .
インフラストラクチャー
導入モデル
Apache RocketMQ デプロイメント アーキテクチャは主に 4 つの部分に分かれています。
プロデューサー プロデューサー
メッセージを投稿したロール。プロデューサは、MQ ロード バランシング モジュールを介したメッセージ配信に対応するブローカー クラスタ キューを選択し、配信プロセスは高速な失敗と再試行をサポートします。
消費者 消費者
メッセージ消費の役割。
- メッセージを消費するためのプッシュ (プッシュ) とプル (プル) の 2 つのモードをサポートします。
- 同時に、クラスターモードとブロードキャストモードの消費もサポートします。
- ほとんどのユーザーのニーズを満たすことができる、リアルタイムのメッセージ サブスクリプション メカニズムを提供します。
ネームサーバー NameServer
NameServer は、トピックとブローカーの動的な登録と検出をサポートする単純なトピック ルーティング レジストリです。
主に次の 2 つの機能が含まれています。
- Broker管理、NameServerはBrokerクラスタの登録情報を受け取り、ルーティング情報の基礎データとして保存します。次に、ブローカーがまだ生きているかどうかを確認するハートビート検出メカニズムを提供します。
- ルーティング情報管理では、各ネームサーバーはブローカー クラスターに関するルーティング情報全体とクライアント クエリのキュー情報を保存します。プロデューサーとコンシューマーは、メッセージを配信および消費するために、ネームサーバーを通じてブローカー クラスター全体のルーティング情報を知ることができます。
通常、NameServer には複数のインスタンスがデプロイされており、インスタンスは相互に通信しません。ブローカーは独自のルーティング情報を各 NameServer に登録するため、各 NameServer インスタンスは完全なルーティング情報を保存します。何らかの理由でネームサーバーがオフラインになっても、クライアントは他のネームサーバーからルーティング情報を取得できます。
プロキシサーバー ブローカー
ブローカーは主に、メッセージの保存、配信、クエリ、およびサービスの高可用性の保証を担当します。
NameServer には状態ノードがほとんどないため、ノード間で情報を同期せずにクラスターにデプロイできます。ブローカーの展開は比較的複雑です。
マスター/スレーブ アーキテクチャでは、ブローカーはマスターとスレーブに分割されます。マスターは複数のスレーブに対応できますが、スレーブは 1 つのマスターにのみ対応できます。マスターとスレーブの対応関係は、同じ BrokerName と異なる BrokerId を指定することによって定義されます。BrokerId は、マスターの場合は 0、スレーブの場合は 0 以外です。マスターは複数展開することもできます。
導入モデルの概要
- 各ブローカーは、ネームサーバー クラスター内のすべてのノードとの長い接続を確立し、トピック情報をすべてのネームサーバーに定期的に登録します。
- プロデューサーは、NameServer クラスター内のノードの 1 つとの長期接続を確立し、定期的に NameServer からトピック ルーティング情報を取得し、トピック サービスを提供するマスターへの長期接続を確立し、定期的にマスターにハートビートを送信します。生産者は完全に無国籍です。
- コンシューマは、NameServer クラスタ内のいずれかのノードとの長期接続を確立し、NameServer からトピック ルーティング情報を定期的に取得し、トピック サービスを提供するマスターおよびスレーブへの長期接続を確立し、マスターおよびスレーブに定期的にハートビートを送信します。コンシューマはマスターまたはスレーブからのメッセージをサブスクライブできます。
RocketMQ クラスターのワークフロー
1.ネームサーバーを起動します
ネームサーバーを起動します。NameServer が開始されると、ポートを監視し、ルーティング コントロール センターに相当する Broker、Producer、Consumer からの接続を待ちます。
2. ブローカーを開始する
ブローカーを開始します。すべてのネームサーバーとの接続を長く維持し、定期的にハートビート パケットを送信します。ハートビート パケットには現在のブローカー情報が含まれており、すべてのトピック情報が保存されます。登録が成功すると、NameServer クラスター内のトピックとブローカーの間にマッピング関係が確立されます。
3. トピックの作成
トピックを作成するときは、トピックを保存するブローカーを指定する必要があります。または、メッセージの送信時にトピックを自動的に作成することもできます。
4. プロデューサーがメッセージを送信
プロデューサーがメッセージを送ります。開始時に、まず NameServer クラスタの 1 つとの長い接続を確立し、現在送信されているトピックがどのブローカーに存在するかを NameServer から取得し、ポーリングしてキュー リストからキューを選択します。その後、ブローカーとの長い接続を確立します。キューが見つかりました。ブローカーにメッセージを送信します。
5. コンシューマはメッセージを受け入れます
コンシューマはメッセージを受け入れます。いずれかのネームサーバーとの長い接続を確立し、現在サブスクライブされているトピックが存在するブローカーを取得し、ブローカーとの接続チャネルを直接確立して、メッセージの消費を開始します。
(トピックは 1 つ以上のサブトピック、つまりメッセージ キューに分割されます)
トピックの下に複数のメッセージ キューを設定できます。メッセージを送信するときに、メッセージのトピックを実行すると、RocketMQ はトピックの下のすべてのキューをポーリングしてメッセージを送信します。メッセージ。次の図は、Broker の内部ニュースを示しています:
いくつかの概念とクラスターの紹介
コンソールのメッセージ詳細 TrackType には
複数の状態があります。
public enum TrackType {
CONSUMED,
CONSUMED_BUT_FILTERED,
PULL,
NOT_CONSUME_YET,
NOT_ONLINE,
UNKNOWN
}
それぞれのタイプについては以下で説明します
タイプ | 説明する |
---|---|
消費された | メッセージが消費されました |
CONSUMED_BUT_FILTERED | メッセージは配信されましたが、フィルタされました |
引く | メッセージの消費方法はプルモードです |
NOT_CONSUME_YET | 現在消費されていない |
NOT_ONLINE | 消費者はオンラインではありません |
未知 | 未知の間違い |
CONSUMED
メッセージが配信され、サブスクライバが ReconsumerLater を返すか、NULL を返すか、例外をスローすると、メッセージは再試行プロセスを経て、メッセージ配信ステータスは CONSUMED になります。
CONSUMED_BUT_FILTERED
メッセージは配信され、フィルタリングされました。たとえば、パブリッシャはメッセージ topicA、tagA をパブリッシュし、サブスクライバは topicA、tagB をサブスクライブします。「メッセージの消費は、サブスクリプション関係、つまりサブスクライブされたトピックとタグの一貫性を満たす必要があります。」 ConsumerGroup 内のすべてのコンシューマは一貫性を維持する必要があります。そうでないとメッセージが失われます。」
NOT_CONSUME_YET
メッセージが配信されていないため、メッセージが蓄積されて消費されていない可能性があります。また、消費スレッドがハングして、消費スレッドの戻りが遅れている可能性もあります。
Rocketmq メッセージ フィルタリングの簡単な説明: ブローカー側フィルタリング、タグ フィルタリング、属性式フィルタリング、クラス フィルタリング、コンシューマ側フィルタリング
基本的な考え方
情報
RocketMQ メッセージの構成は非常にシンプルです。
- topic は、送信されるメッセージのトピックを示します。
- body はメッセージの保存内容を表します
- プロパティはメッセージのプロパティを表します
- transactionId はトランザクション メッセージで使用されます。
- タグ: RocketMQ のタグ フィルタリングでも遅延メッセージでも、プロパティ メッセージ属性メカニズムが使用されます。これらの特別な情報は、システムによって予約された属性 Key を使用します。カスタム属性を設定するときは、システム属性 Key との競合を避ける必要があります。
- キー: サーバーはキーに基づいてハッシュ インデックスを作成します。設定後、コンソール システムでトピックとキーに基づいてメッセージをクエリできます。ハッシュ インデックスであるため、キーが可能な限り一意であることを確認してください。注文番号、製品IDなど
Message で設定できるプロパティ値は次のとおりです。
鬼ごっこ
トピックとタグはどちらもビジネスにおける分類に使用される識別子ですが、違いはTopic 是一级分类
ですTag 可以理解为是二级分类
。タグを使用してトピック内のメッセージをフィルタリングします。
- トピック:
消息主题
、さまざまなビジネス メッセージをトピックごとに分類します。- タグ:
消息标签
は、特定のトピックの下でメッセージの分類をさらに区別するために使用されます。これは、メッセージがプロデューサーから送信されるときに伝えられる属性です。
トピックとタグの関係は下図のようになります。
トピックはいつ使用する必要があり、いつタグを使用する必要がありますか?
それは次のような観点から判断できます。
- 通常のメッセージ、トランザクションメッセージ、タイミング(遅延)メッセージ、シーケンシャルメッセージなど、メッセージタイプが一致しているかどうか メッセージタイプごとに使用するトピックが異なるため、タグでは区別できません。
- ビジネスに関連性があるかどうか: 淘宝網の取引ニュース、京東物流のニュースなど、直接関係のないニュースは区別するために異なるトピックを使用しますが、同じ天猫の取引ニュース、電化製品の注文、婦人服の注文、化粧品の注文のニュースでも使用できます。タグ 区別を付けます。
- メッセージの優先度が同じかどうか: 同じ物流メッセージの場合、Hema は数時間以内に配達する必要があり、Tmall スーパーマーケットは 24 時間以内に配達され、淘宝網の物流は比較的遅くなります。優先順位が異なるメッセージは、異なるトピックによって区別されます。
- メッセージの規模は等しいですか? 一部のビジネス メッセージはサイズが小さいですが、高いリアルタイム パフォーマンスが必要です。数兆レベルのメッセージと同じトピックを使用すると、長すぎるメッセージにより「餓死」する可能性があります。場合によっては、異なる大きさのメッセージを分割し、異なるトピックを使用する必要があります。
- 一般に、メッセージ分類では、複数のトピックを作成するか、同じトピックの下に複数のタグを作成するかを選択できます。しかし、通常、異なるトピック間のメッセージ間には必然的なつながりはなく、完全なセットとサブセットの関係、一連の処理の関係など、同じトピック内の相互に関連するメッセージを区別するためにタグが使用されます。
キー
Apache RocketMQ の各メッセージには、ビジネス レベルで一意の識別コード キー フィールドを設定できます。これは、将来のメッセージ損失の問題を特定するのに便利です。ブローカーはメッセージごとにインデックス (ハッシュ インデックス) を作成し、アプリケーションはトピックとキーを通じてメッセージの内容とメッセージを消費するユーザーをクエリできます。これはハッシュ インデックスであるため、潜在的なハッシュの衝突を避けるために、キーができるだけ一意であることを確認してください。
// 订单Id
String orderId = "20034568923546";
message.setKeys(orderId);
列
高い同時実行性と水平拡張をサポートするには、トピックを分割する必要があります。RocketMQ では、これはキューと呼ばれます。トピックには複数のキューがあり、異なるブローカーに分散される場合があります。
一般に、メッセージが繰り返し送信されない場合 (サーバーが応答しないため再試行する場合など)、そのメッセージはトピックのキューの 1 つにのみ存在します。メッセージは先入れ先順に従ってキューに格納されます。 -out の原則 各メッセージには独自の位置があり、各キューは現在のメッセージの総数をカウントします (最大位置 MaxOffset と呼ばれます)。キューの開始位置に対応する位置は開始位置 MinOffset と呼ばれます。キューを使用すると、メッセージの送信と消費の同時実行性を向上させることができます。
プロデューサー
プロデューサー (Producer) はメッセージの送信者です。Apache RocketMQ には豊富なメッセージ タイプがあり、さまざまなアプリケーション シナリオをサポートできます。さまざまなシナリオでは、送信にさまざまなメッセージを使用する必要があります。
たとえば、電子商取引トランザクションでタイムアウト内に支払いを行わずに注文を閉じるシナリオでは、注文の作成時に遅延メッセージが送信されます。
このメッセージは 30 分後に消費者に配信されます。このメッセージを受け取った後、消費者は対応する注文が支払われたかどうかを判断する必要があります。
支払いが完了していない場合、注文はクローズされます。
すでに支払いが行われている場合は無視されます。——この種のシナリオを使用する必要があります延迟消息
。
電子商取引のシナリオでは、ビジネスでは同じ順序のメッセージを厳密な順序で保持する必要があるため、この時点で使用する必要があります顺序消息
。
ログ処理シナリオでは、比較的大きな送信遅延は許容されますが、スループット要件は高く、現時点で使用できる 1 秒あたり数百万のログを処理できることが期待されています批量消息
。
銀行引き落としのシナリオでは、上流の引き落とし操作と下流の SMS 通知の一貫性を保つ必要があるため、この時点で使用する必要があります事务消息
。
運用環境では、運用および保守プロセスにおけるリスクやエラーを回避するために、異なるメッセージ タイプは異なるトピックを使用する必要があり、同じトピック内で複数のメッセージ タイプを使用しないことに注意してください。
次の rocketMQ の記事では、統合 springboot の使用方法を紹介します~~