このトピックでは、ApsaraMQ for RocketMQのメッセージ送信再試行メカニズムとスロットリングメカニズムについて説明します。
背景
メッセージ送信の再試行
ApsaraMQ for RocketMQの送信再試行メカニズムは、次の質問に答えます。
- 一部のノードに障害がある場合、メッセージを送信できますか?
- 再試行要求は呼び出しスレッドをブロックしますか?
- 再試行を送信することの欠点は何ですか?
スロットリング
ApsaraMQ for RocketMQのスロットリングメカニズムは、次の質問に答えます。
- スロットルはどのような状況でトリガーされますか?
- スロットリングがトリガーされたときのクライアントの動作は何ですか?
- スロットルのトリガーを回避する方法と、予期しないスロットルを処理する方法?
メッセージ送信の再試行
再試行の送信の概要
ApsaraMQ for RocketMQのプロデューサークライアントがブローカーを呼び出してメッセージを送信すると、ネットワーク障害やサービス例外などの理由で呼び出しが失敗することがあります。 メッセージの信頼性を確保するために、ApsaraMQ for RocketMQは、リクエストが成功するまで失敗したリクエストを再試行するための組み込みロジックをクライアントSDKに提供しています。
メッセージ送信の再試行は、同期送信モードと非同期送信モードの両方でサポートされます。
トリガー条件
送信の再試行は、次のいずれかの条件によってトリガーされます。
- クライアントからの呼び出しが失敗するか、リクエストがタイムアウトします。
- ネットワーク例外は、接続失敗または要求タイムアウトを引き起こします。
- ブローカーノードがシャットダウンまたは再起動されているため、接続が閉じられます。
- ブローカーの実行が遅いため、リクエストがタイムアウトします。
- ブローカーはエラーコードを返します。
- ロジックエラー: 正しくない実行ロジックによって発生したエラー。
- スロットル: 過剰なトラフィックによってトリガーされるスロットル。
説明 トランザクションメッセージの場合、透過的な再試行のみが実行されます。 ネットワーク例外またはタイムアウトシナリオでは再試行は実行されません。
再試行プロセス
プロデューサーがメッセージを初期化するときに、プロデューサーの最大再試行回数を指定できます。 上記のいずれかのトリガー条件が発生すると、プロデューサークライアントは、メッセージが送信されるか、または再試行の最大数に達するまで、メッセージを再送信しようとします。 最後の再試行で失敗が続く場合、コールエラーが返されます。
- 同期送信: 再試行が成功するか、最後の再試行が失敗するまで、呼び出しスレッドはブロックされます。 最後の再試行が失敗した場合、システムはエラーコードと例外を返します。
- 非同期送信: 呼び出しスレッドはブロックされていません。 呼び出し結果は、例外イベントまたは成功イベントとして返されます。
再試行間隔
- メッセージは、スロットリングによって再試行がトリガーされた場合を除き、失敗時に直ちに再試行されます。
- スロットリングによって再試行がトリガーされた場合、メッセージは指数バックオフプロトコルで指定された間隔で再試行されます。 指数バックオフアルゴリズムは、次のパラメーターを使用して再試行動作を制御します。
- INITIAL_BACKOFF: 最初の失敗と最初の再試行の間隔を指定します。 デフォルト値: 1秒。
- MULTIPLIER: 各失敗した再試行後の間隔を乗算する係数を指定します。 デフォルト値: 1.6
- JITTER: 間隔をランダム化する係数を指定します。 デフォルト値: 0.2
- MAX_BACKOFF: 間隔の上限を指定します。 デフォルト値: 120秒。
- MIN_CONNECT_TIMEOUT: 最小間隔を指定します。 デフォルト値: 20秒。
ConnectWithBackoff() current_backoff = INITIAL_BACKOFF current_deadline = now() + INITIAL_BACKOFF (TryConnect(Max(current_deadline, now() + MIN_CONNECT_TIMEOUT))!= SUCCESS) SleepUntil(current_deadline) current_backoff = Min(current_backoff * マルチプレイヤー、MAX_BACKOFF) current_deadline = now() + current_backoff + UniformRandom(-JITTER * current_backoff, JITTER * current_backoff)
詳細については、「connection-backoff.md」をご参照ください。
制限事項
- リンクブロッキング評価: 再試行メカニズムから、プロデューサーが再試行プロセスの最大再試行回数のみを設定できることがわかります。 システム例外がSDKの組み込みの再試行ロジックをトリガーする場合、ブローカーは最終的な再試行結果を待つ必要があり、送信リクエストリンクはブロックされます。 したがって、再試行がリンクをブロックしないように、各呼び出しのタイムアウト時間と最大再試行回数を評価する必要があります。
- 最終例外の処理: ApsaraMQ for RocketMQクライアントの組み込みの送信再試行メカニズムでは、失敗したメッセージが正常に送信されることが保証されません。 それでも最終的な再試行が失敗した場合、呼び出し元は例外をキャプチャし、メッセージ送信結果の不一致を防ぐために冗長保護を提供する必要があります。
- メッセージの重複: ApsaraMQ for RocketMQプロデューサークライアントがメッセージを再送信すると、クライアントはブローカーで失敗したと思われるメッセージの処理結果を知りません。 その結果、重複メッセージがブローカーに存在する可能性があります。 ビジネスロジックがこのような状況に適切に対応できることを確認してください。
スロットリング
スロットルの概要
システム容量使用量がしきい値を超えると、ApsaraMQ for RocketMQブローカーはリクエストを拒否し、基になるリソースへの過負荷を回避するためにエラーを返します。
トリガー条件
ApsaraMQ for RocketMQのスロットリングメカニズムは、次のいずれかの条件によってトリガーされます。
- 高いストレージ負荷: Consumer progress managementのWorking mechanismセクションで説明されているように、コンシューマーグループはキューの最大オフセットからメッセージの消費を開始します。 コンシューマグループがより早い時点から消費する必要がある場合、キューのストレージ負荷が急増し、スロットリングがトリガーされます。 これは、新しいビジネス展開などのバックトラックシナリオで発生します。
- ブローカーでの過剰な未消費メッセージ: コンシューマーがメッセージを送信するのと同じレートで消費できない場合、リクエストはキューに蓄積されます。 積み上げられたメッセージの数がしきい値を超えると、スロットリングがトリガーされ、下流システムの負担が軽減されます。
行動
スロットリングがトリガーされると、プロデューサークライアントは次のエラーメッセージと例外を受け取ります。
- 返信コード: 530
- 返信テキスト: TOO_MANY_REQUESTS
これらを受信すると、クライアントは、指数バックオフプロトコルに従ってメッセージを再試行する。 詳細については、「メッセージ送信の再試行」をご参照ください。
提案事項
- トリガー調整を回避する方法: 観測可能なメトリックを使用してシステム容量を監視し、それに応じて基になるリソースをスケールします。
- スロットリングの処理方法: クライアントでスロットリングがトリガーされ、組み込みの再試行プロセスが失敗した場合、一時的に別のシステムに呼び出しを切り替えることができます。