RocketMQ ソースコード分析—コンシューマ

消費者がプロセスを開始する

画像.png

画像.png

画像.png

DefaultMQPushConsumerImpl クラスがコアクラスです

画像.png

画像.png

消費者モデル

クラスターの消費

画像.png

Consumer Group 内の各 Consumer インスタンスはメッセージの消費を共有します。つまり、メッセージは Consumer Group 内の 1 つのインスタンスにのみ配信されます。

実際、各コンシューマは Message Queue のキャンセル料を均等に負担します。たとえば、トピックに 3 つのキューがあり、コンシューマ グループの 1 つに 3 つのインスタンス (おそらく 3 つのプロセスまたは 3 つのマシン) がある場合、各インスタンスは 1 つのキュー メッセージのみを消費します。

プロデューサーがメッセージを送信するとき、すべてのキューをポーリングするため、メッセージはさまざまなキューに均等に分散され、キュー上のメッセージは平均的であると考えることができます。その後、インスタンスはメッセージを均等に消費します。

このモードでは、消費の進行状況 (コンシューマー オフセット)のストレージ が Broker に永続化されます

無線消費量

画像.png

メッセージは、コンシューマ グループの下の各コンシューマ インスタンスに配信されます。これらのコンシューマが同じコンシューマ グループに属している場合でも、メッセージはコンシューマ グループ内の各コンシューマによって 1 回ずつ消費されます。

このモードでは、消費の進行状況 (コンシューマ オフセット) が ローカルに保存され、インスタンスに永続化されます

消費者の負荷分散

クラスタモード

クラスター消費モードでは、各メッセージは、このトピックをサブスクライブするコンシューマー グループ内の 1 つのインスタンスに配信するだけで済みます。RocketMQ は、アクティブなプルを使用してメッセージをプルおよび消費します。プルする場合は、どのメッセージ キューをプルするかを明確に指定する必要があります。

インスタンスの数が変化すると、すべてのインスタンスの負荷分散がトリガーされ、キューの数とインスタンスの数に応じてキューが各インスタンスに均等に分散されます。

デフォルトの割り当てアルゴリズムは AllocateMessageQueueAveragely ですが、別の平均アルゴリズムとして AllocateMessageQueueAveragelyByCircle があります。これも各キューを均等に割り当てますが、キューを循環的に割り当てます。

以下に示すように:

画像.png

クラスター モードでは、キューで割り当てられるインスタンスは 1 つだけであることに注意してください。これは、複数のインスタンスがキューからメッセージを同時に消費する場合、コンシューマーがどのメッセージをプルするかをアクティブに制御するため、結果的に同じメッセージが生成されるためです。異なるインスタンスで複数回消費されるため、アルゴリズム的には 1 つのキューは 1 つのコンシューマ インスタンスにのみ割り当てられ、1 つのコンシューマ インスタンスを同時に異なるキューに割り当てることができます。

コンシューマ インスタンスを追加してキューの消費を共有することで、消費機能を水平方向に拡張する役割を果たすことができます。インスタンスがオフラインになると、負荷分散が再度トリガーされ、最初に割り当てられていたキューは他のインスタンスに割り当てられ、消費が継続されます。

ただし、コンシューマ インスタンスの数がメッセージ キューの総数より大きい場合、追加のコンシューマ インスタンスはキューに割り当てられず、メッセージは消費されず、負荷は共有されません。したがって、キューの総数がコンシューマーの数以上になるように制御する必要があります。

画像.png

ブロードキャストモード

ブロードキャスト モードでは、コンシューマ グループ内のすべてのコンシューマ インスタンスにメッセージが配信される必要があるため、メッセージの共有消費などはありません。

実装の点での違いの 1 つは、コンシューマがキューを割り当てるときに、すべてのコンシューマがすべてのキューに割り当てられることです。

同時消費プロセス

一般に、消費するときにコールバック関数を使用します。最も一般的に使用される方法は同時消費です。コンシューマ クライアントのコードは次のとおりです。

画像.png

RocketMQ を使用するときの全体的なプロセスは次のとおりです。

画像.png

トピック構成情報の取得

コンシューマが起動した後の最初のステップは、ネームサーバーからトピック関連情報を取得することです。このステップはコンポーネント間で対話するように設計されており、RocketMQ は関数番号を使用して設計します。

画像.png

画像.png

画像.png

最後に、MQClientAPIImpl クラスで呼び出しが完了します。

画像.png

グループの ConsumerList を取得する

メッセージを消費する前に、現在のグループが消費した関連情報を取得する必要があります: ConsumerList

画像.png

ブロードキャスト消費モードの場合、サーバーから消費の進行状況を取得する必要はありません (ブロードキャスト消費モードは進行状況をコンシューマ側でローカルに保存します)。

画像.png

ブロードキャスト消費モードでは、次のように、消費進行状況関連情報をサーバーから取得する必要があります。

画像.png

画像.png

キューの消費オフセットを取得する

コンシューマに対応するキューを割り当てた後、クラスタモードの場合は、その後の未消費メッセージの取得を容易にするために、コンシューマに対応するキューの消費オフセットを取得する必要があります。
画像.png

RebalancePushImpl クラスを入力します

画像.png画像.png

画像.png

画像.png

画像.png

キューからメッセージをプルする

画像.png

画像.png

最後に、DefaultMQPushConsumerImpl クラスの pullMessage メソッドを入力します。

画像.png

画像.png

画像.png

キューの消費オフセットを更新します

RocketMQ のプッシュ モードはプル モードに基づいて実装されているため、メッセージはバッチでプルされるため、バッチをプルしてオフセットを一度送信することはできません。そのため、ここではスケジュールされたタスクを使用してオフセットを更新します。

画像.png

画像.png

画像.png

順次消費プロセス

シーケンシャル消費コード:画像.pngシーケンシャル消費のプロセスは、同時消費のプロセスに似ています。唯一の違いは、ロック メカニズムを使用してキューを同時に 1 つのコンシューマのみが消費できるようにすることです。消費。

ConsumeMessageOrderlyServiceクラス

画像.png

ここには 20 秒ごとに実行されるスケジュールされたタスクがあります (ロックを定期的に更新するため、ロックの有効期間は 60 秒です)。

画像.png

画像.png

画像.png

消費の問題

消費の停滞

消費プロセス、特に連続メッセージの場合、スタック現象が発生します。連続メッセージはブローカーでロックする必要があるため、コンシューマーの 1 つがハングアップすると、ブローカー層がロックを維持するのに 60 秒かかります。したがって、この期間中、消費者は消費できず、ロックを待つことになります。

また、ブローカー層もダウンしている場合、マスタースレーブ構造の場合はマスターノードを使用してロックを取得し、マスターノードがダウンしている場合はスレーブ消費を使用しますが、ロックは発生しません。スレーブノードなので、このように連続メッセージが発生した場合、場合によっては妨害が発生している可能性もあります。

画像.png

画像.png

画像.png

起動してから消費するまでに時間がかかる

同時消費中に、多数のコンシューマーを開始したり、多数のトピックを維持したり、または多数のキューが存在したりすると、消費プロセスの相互作用には複数のスレッドを開始し、多くの作業を実行する必要があることがわかります。やるべきことがたくさんあるので、それをやり始めるまでに時間がかかるように感じます。

おすすめ

転載: blog.csdn.net/qq_28314431/article/details/133036609
おすすめ