このトピックでは、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 while (TryConnect(Max(current_deadline, now() + MIN_CONNECT_TIMEOUT))!= SUCCESS) SleepUntil(current_deadline) current_backoff = Min(current_backoff * MULTIPLIER, MAX_BACKOFF) current_deadline = now() + current_backoff + UniformRandom(-JITTER * current_backoff, JITTER * current_backoff)詳細については、「connection-backoff.md」をご参照ください。
機能制限
リンクブロッキング評価: ApsaraMQ for RocketMQのメッセージ送信再試行メカニズムでは、プロデューサーは再試行の最大数のみを設定できます。 システム例外がSDKの組み込みの再試行ロジックをトリガーする場合、ブローカーは最終的な再試行結果を待つ必要があります。 これは、要求リンクをブロックし得る。 したがって、再試行がリクエストリンクをブロックしないように、タイムアウト時間と各リクエストの最大再試行回数を評価する必要があります。
例外の処理: ApsaraMQ for RocketMQクライアントの組み込みメッセージ送信再試行メカニズムでは、失敗したメッセージが正常に送信されることが保証されません。 前回の再試行でメッセージの送信に失敗した場合、呼び出し元は例外をキャプチャし、冗長保護を提供してメッセージ送信結果の不一致を防ぐ必要があります。
重複したメッセージ: ApsaraMQ for RocketMQプロデューサークライアントがリクエストタイムアウトのためにメッセージを再送信した場合、クライアントはブローカーでのメッセージの処理結果を知りません。 その結果、重複メッセージがブローカーに存在する可能性があります。 メッセージ消費ロジックが重複したメッセージを適切に処理できることを確認してください。
メッセージスロットリング
メッセージ調整とは何ですか?
ApsaraMQ for RocketMQでは、システム容量が不十分になった場合、またはシステム使用量が指定されたしきい値を超えた場合に、基になるリソースに対する過度に高いワークロードを防ぐために、メッセージスロットリングがトリガーされます。 メッセージスロットリングがトリガーされると、ApsaraMQ for RocketMQブローカーはすぐに失敗し、システムスロットリングエラーを返します。
トリガー条件
メッセージスロットリングは、次のシナリオでApsaraMQ for RocketMQでトリガーできます。
ストレージの負荷が高い: コンシューマグループは、キューの最大オフセットからメッセージを消費し始めます。 詳細については、「Consumer progress management」をご参照ください。 ビジネス展開などのシナリオでは、コンシューマグループは特定の時間にメッセージを消費する必要があります。 この場合、キューのストレージ圧力が急上昇し、スロットルがトリガーされます。
ブローカー上の過剰な未消費メッセージ: コンシューマーがメッセージを送信するのと同じレートでメッセージを消費できない場合、多数のメッセージがキューに蓄積される可能性があります。 蓄積されたメッセージの数がしきい値を超えると、メッセージスロットリングがトリガーされ、ダウンストリームシステムのワークロードが軽減されます。
行動
メッセージスロットリングがトリガーされると、クライアントはシステムスロットリングエラーを受け取ります。 次の項目は、さまざまなタイプのクライアントが受信するエラーコードとエラーメッセージを示しています。
gRPC
エラーコード: 530
エラーメッセージのキーワード: TOO_MANY_REQUESTS
クライアントがシステムスロットリングエラーコードを受信すると、クライアントは、指数バックオフ再試行ポリシーで指定された間隔に基づいて、失敗したメッセージを再試行します。 詳細については、「メッセージ送信の再試行」をご参照ください。
Remoting
エラーコード: 215
エラーメッセージキーワード: メッセージフロー制御
バージョンが1.9.0より前のApsaraMQ for RocketMQ TCP client SDK for Javaを使用するクライアントがシステムスロットリングエラーコードを受信した場合、クライアントは失敗したメッセージを再試行しません。 ApsaraMQ for RocketMQ TCPクライアントSDK for Java 1.9.0.Final以降を使用するクライアントがシステムスロットリングエラーコードを受信すると、クライアントは指数関数的バックオフ再試行ポリシーに基づいて失敗したメッセージを再試行します。 詳細については、「メッセージ送信の再試行」をご参照ください。
オープンソースのApache RocketMQ SDKを使用するプロデューサークライアントがシステムスロットリングエラーコードを受け取った場合、クライアントは失敗したメッセージを再試行しません。 オープンソースのApache RocketMQ SDKを使用するコンシューマークライアントがシステムスロットリングエラーコードを受信すると、クライアントは指数関数的バックオフ再試行ポリシーに基づいて失敗したメッセージを再試行します。
サポートされているgRPCおよびRemotingクライアントのバージョンについては、「説明」をご参照ください。
提案事項
スロットルがトリガーされないようにする方法: 可観測機能を使用して、システムの使用状況と容量を監視します。 これにより、基盤となるリソースが十分に確保されます。
予期しないメッセージスロットリングを処理する方法: 予期しないメッセージスロットリングがトリガーされ、組み込みの再試行プロセスがクライアントで失敗した場合、リクエストを一時的に別のシステムに切り替えることをお勧めします。