記事ディレクトリ
消費者がプロセスを開始する
DefaultMQPushConsumerImpl クラスがコアクラスです
消費者モデル
クラスターの消費
Consumer Group 内の各 Consumer インスタンスはメッセージの消費を共有します。つまり、メッセージは Consumer Group 内の 1 つのインスタンスにのみ配信されます。
実際、各コンシューマは Message Queue のキャンセル料を均等に負担します。たとえば、トピックに 3 つのキューがあり、コンシューマ グループの 1 つに 3 つのインスタンス (おそらく 3 つのプロセスまたは 3 つのマシン) がある場合、各インスタンスは 1 つのキュー メッセージのみを消費します。
プロデューサーがメッセージを送信するとき、すべてのキューをポーリングするため、メッセージはさまざまなキューに均等に分散され、キュー上のメッセージは平均的であると考えることができます。その後、インスタンスはメッセージを均等に消費します。
このモードでは、消費の進行状況 (コンシューマー オフセット)のストレージ が Broker に永続化されます。
無線消費量
メッセージは、コンシューマ グループの下の各コンシューマ インスタンスに配信されます。これらのコンシューマが同じコンシューマ グループに属している場合でも、メッセージはコンシューマ グループ内の各コンシューマによって 1 回ずつ消費されます。
このモードでは、消費の進行状況 (コンシューマ オフセット) が ローカルに保存され、インスタンスに永続化されます。
消費者の負荷分散
クラスタモード
クラスター消費モードでは、各メッセージは、このトピックをサブスクライブするコンシューマー グループ内の 1 つのインスタンスに配信するだけで済みます。RocketMQ は、アクティブなプルを使用してメッセージをプルおよび消費します。プルする場合は、どのメッセージ キューをプルするかを明確に指定する必要があります。
インスタンスの数が変化すると、すべてのインスタンスの負荷分散がトリガーされ、キューの数とインスタンスの数に応じてキューが各インスタンスに均等に分散されます。
デフォルトの割り当てアルゴリズムは AllocateMessageQueueAveragely ですが、別の平均アルゴリズムとして AllocateMessageQueueAveragelyByCircle があります。これも各キューを均等に割り当てますが、キューを循環的に割り当てます。
以下に示すように:
クラスター モードでは、キューで割り当てられるインスタンスは 1 つだけであることに注意してください。これは、複数のインスタンスがキューからメッセージを同時に消費する場合、コンシューマーがどのメッセージをプルするかをアクティブに制御するため、結果的に同じメッセージが生成されるためです。異なるインスタンスで複数回消費されるため、アルゴリズム的には 1 つのキューは 1 つのコンシューマ インスタンスにのみ割り当てられ、1 つのコンシューマ インスタンスを同時に異なるキューに割り当てることができます。
コンシューマ インスタンスを追加してキューの消費を共有することで、消費機能を水平方向に拡張する役割を果たすことができます。インスタンスがオフラインになると、負荷分散が再度トリガーされ、最初に割り当てられていたキューは他のインスタンスに割り当てられ、消費が継続されます。
ただし、コンシューマ インスタンスの数がメッセージ キューの総数より大きい場合、追加のコンシューマ インスタンスはキューに割り当てられず、メッセージは消費されず、負荷は共有されません。したがって、キューの総数がコンシューマーの数以上になるように制御する必要があります。
ブロードキャストモード
ブロードキャスト モードでは、コンシューマ グループ内のすべてのコンシューマ インスタンスにメッセージが配信される必要があるため、メッセージの共有消費などはありません。
実装の点での違いの 1 つは、コンシューマがキューを割り当てるときに、すべてのコンシューマがすべてのキューに割り当てられることです。
同時消費プロセス
一般に、消費するときにコールバック関数を使用します。最も一般的に使用される方法は同時消費です。コンシューマ クライアントのコードは次のとおりです。
RocketMQ を使用するときの全体的なプロセスは次のとおりです。
トピック構成情報の取得
コンシューマが起動した後の最初のステップは、ネームサーバーからトピック関連情報を取得することです。このステップはコンポーネント間で対話するように設計されており、RocketMQ は関数番号を使用して設計します。
最後に、MQClientAPIImpl クラスで呼び出しが完了します。
グループの ConsumerList を取得する
メッセージを消費する前に、現在のグループが消費した関連情報を取得する必要があります: ConsumerList
ブロードキャスト消費モードの場合、サーバーから消費の進行状況を取得する必要はありません (ブロードキャスト消費モードは進行状況をコンシューマ側でローカルに保存します)。
ブロードキャスト消費モードでは、次のように、消費進行状況関連情報をサーバーから取得する必要があります。
キューの消費オフセットを取得する
コンシューマに対応するキューを割り当てた後、クラスタモードの場合は、その後の未消費メッセージの取得を容易にするために、コンシューマに対応するキューの消費オフセットを取得する必要があります。
RebalancePushImpl クラスを入力します
キューからメッセージをプルする
最後に、DefaultMQPushConsumerImpl クラスの pullMessage メソッドを入力します。
キューの消費オフセットを更新します
RocketMQ のプッシュ モードはプル モードに基づいて実装されているため、メッセージはバッチでプルされるため、バッチをプルしてオフセットを一度送信することはできません。そのため、ここではスケジュールされたタスクを使用してオフセットを更新します。
順次消費プロセス
シーケンシャル消費コード:シーケンシャル消費のプロセスは、同時消費のプロセスに似ています。唯一の違いは、ロック メカニズムを使用してキューを同時に 1 つのコンシューマのみが消費できるようにすることです。消費。
ConsumeMessageOrderlyServiceクラス
ここには 20 秒ごとに実行されるスケジュールされたタスクがあります (ロックを定期的に更新するため、ロックの有効期間は 60 秒です)。
消費の問題
消費の停滞
消費プロセス、特に連続メッセージの場合、スタック現象が発生します。連続メッセージはブローカーでロックする必要があるため、コンシューマーの 1 つがハングアップすると、ブローカー層がロックを維持するのに 60 秒かかります。したがって、この期間中、消費者は消費できず、ロックを待つことになります。
また、ブローカー層もダウンしている場合、マスタースレーブ構造の場合はマスターノードを使用してロックを取得し、マスターノードがダウンしている場合はスレーブ消費を使用しますが、ロックは発生しません。スレーブノードなので、このように連続メッセージが発生した場合、場合によっては妨害が発生している可能性もあります。
起動してから消費するまでに時間がかかる
同時消費中に、多数のコンシューマーを開始したり、多数のトピックを維持したり、または多数のキューが存在したりすると、消費プロセスの相互作用には複数のスレッドを開始し、多くの作業を実行する必要があることがわかります。やるべきことがたくさんあるので、それをやり始めるまでに時間がかかるように感じます。