負荷制限リファレンスガイド
experimental|
この技術は、experimentalと考えられています。 experimental モードでは、アイデアを成熟させるために早期のフィードバックが求められます。ソリューションが成熟するまでの間、プラットフォームの安定性や長期的な存在を保証するものではありません。フィードバックは メーリングリスト や GitHubの課題管理 で受け付けています。 とりうるステータスの完全なリストについては、 FAQの項目 を参照してください。 |
負荷制限は、サービスの過負荷を検出し、リクエストを拒否する手法です。過負荷時にリクエストを拒否することで、負荷制限はアプリケーションを稼働させ続けます。優先負荷制限を使用すると、アプリケーションは機能低下した状態であっても稼働し続けます。つまり、リクエストの一部のみが処理され、残りは早期に拒否されます。アプリケーションが過負荷になる実際の危険性がある動的な環境で実行されており、すでに負荷制限を行う他のサービスが前面にない場合に、これを使用することを検討する必要があります。
Quarkus では、 quarkus-load-shedding エクステンションによって負荷制限メカニズムが提供されます。
1. 負荷制限エクステンションの使用
負荷制限エクステンションを使用するには、プロジェクトに io.quarkus:quarkus-load-shedding エクステンションを追加する必要があります。
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-load-shedding</artifactId>
</dependency>
implementation("io.quarkus:quarkus-load-shedding")
追加すると、負荷制限が有効になります。 quarkus.load-shedding.enabled を false に設定することで無効にできます。
負荷制限には、純粋なものと優先度ベースの 2 種類があります。純粋な負荷制限は、過負荷が検出されるとすべてのリクエストを拒否します。優先度ベースの負荷制限は、過負荷が検出された場合でも、アプリケーションで定義された基準に基づいてリクエストの一部のみを拒否します。デフォルトでは、優先負荷制限が有効になっています。 quarkus.load-shedding.priority.enabled を false に設定することで無効にできます。
優先負荷制限をカスタマイズするには 2 つの方法があります:
-
io.quarkus.load.shedding.RequestPrioritizerを実装することで、アプリケーションはどのリクエストを早期に拒否できるか、そしてどのリクエストを他に選択肢がない場合にのみ拒否できるかを決定できます。 -
io.quarkus.load.shedding.RequestClassifierを実装することで、アプリケーションはリクエストを独立して拒否されるコホートに分類できます。
その他の設定オプションについては以下に説明しますが、通常は変更しないでください。
2. 負荷制限アルゴリズム
負荷制限アルゴリズムには 2 つの部分があります。
-
過負荷検出
-
優先負荷制限 (オプション)
2.1. 過負荷検出
現在のサービスが過負荷かどうかを検出するために、TCP Vegas を応用しています。
このアルゴリズムは、設定可能な処理中のリクエストの制限 (デフォルトでは 100) から始まります。現在の同時処理中のリクエスト数がこの制限に達すると、過負荷状態が通知されます。
これはそれほど興味深い点ではありませんが、このアルゴリズムはリクエストキューのサイズに基づいて動的に制限を調整します。キューが短い場合、より多くのリクエストが処理でき、制限が増加します。キューが長い場合、処理できるリクエストが減り、制限が減少します。制限を無期限に増やすことはできません。設定可能な最大値があり、デフォルトでは 1000 です。
ただし、監視できる実際のリクエストキューはないため、このアルゴリズムは以前に観測された応答時間に基づいてリクエストキューの現在の長さを推定します。最近のリクエストが、最近の最低応答時間と比較して長くかかるほど、キューも長いと推定されます。
2.2. 優先負荷制限
過負荷状況が通知されると、優先負荷制限が呼び出されます。
優先負荷制限が無効になっている場合、何もせず、すべてのリクエストは直ちに拒否されます。しかし、デフォルトでは優先負荷制限が有効になっており、現在の CPU 負荷が十分に高い場合にのみリクエストが拒否されます。
| 優先負荷制限は現在、常に CPU 負荷に基づいています。他のメカニズム (ネットワーク使用率など) も可能ですが、現在は実装されていません。 |
リクエストを拒否するかどうかを判断するには、2 つの属性が考慮されます。
-
リクエストの優先度
-
リクエストコホート
静的に定義された優先度が 5 つ、コホートが 128 あり、合計で 640 のリクエストグループになります。
優先度とコホートの両方がリクエストに割り当てられた後、リクエストグループ番号が計算されます。優先度の高いリクエストほどグループ番号は小さく、優先度の低いリクエストほどグループ番号は大きくなります。グループ番号が現在の CPU 負荷よりも大きい場合、リクエストは拒否されます。そうでない場合は、過負荷状況でも許可されます。
実際、グループ番号は CPU 負荷と直接比較されるのではなく、CPU 負荷の関数と比較されます。この関数は (1 - load^3) * 640 であり、 load は 0.0 から 1.0 までの数値としての CPU 負荷、640 は前述のリクエストグループの数です。
|
2.2.1. リクエストの優先度のカスタマイズ
優先度は io.quarkus.load.shedding.RequestPrioritizer によって割り当てられます。
io.quarkus.load.shedding.RequestPriority 列挙には、 CRITICAL、 IMPORTANT、 NORMAL、 BACKGROUND、 DEGRADED の 5 つの静的に定義された優先度があります。
デフォルトでは、リクエスト prioritizer が適用されない場合、優先度は NORMAL であると見なされます。
デフォルトの prioritizer が 1 つあり、非アプリケーションエンドポイントへのリクエストには優先度 CRITICAL が割り当てられます。
@Priority は宣言されていません。
RequestPrioritizer インターフェイスのカスタム実装を定義することが可能です。
実装は CDI Bean である必要があり、そうでない場合は無視されます。
typesafe な解決の CDI ルールに従う必要があります。
つまり、異なる @Priority 値を持つ複数の実装が存在し、そのうちのいくつかが @Alternative である場合、最も高い優先度値を持つ代替実装のみが保持されます。
代替実装となる実装がない場合、すべての実装が保持され、 @Priority の降順で並べ替えられます (最も高い優先度の値が最初になります)。
2.2.2. リクエストコホートのカスタマイズ
コホートは io.quarkus.load.shedding.RequestClassifier によって割り当てられます。
静的に定義されたコホートは 128 あり、最小番号は 1、最大番号は 128 です。
分類子はこの範囲内の番号を返す必要があります。返さない場合、番号が自動的に調整されます。
リモート IP アドレスと現在の時刻のハッシュに基づいてコホートを割り当てるデフォルトの分類子が 1 つあり、IP アドレスのコホートはおよそ 1 時間ごとに変更されます。
@Priority は宣言されていません。
RequestClassifier インターフェイスのカスタム実装を定義することが可能です。
実装は CDI Bean である必要があり、そうでない場合は無視されます。
typesafe な解決の CDI ルールに従う必要があります。
つまり、異なる @Priority 値を持つ複数の実装が存在し、そのうちのいくつかが @Alternative である場合、最も高い優先度値を持つ代替実装のみが保持されます。
代替実装となる実装がない場合、すべての実装が保持され、 @Priority の降順で並べ替えられます (最も高い優先度の値が最初になります)。
3. 制限
負荷制限エクステンションは現在、HTTP リクエストにのみ適用され、リクエスト/レスポンスのネットワークインタラクションに大きく偏っています。 そのため、gRPC、WebSocket、その他の HTTP 経由のストリーミングはサポートされていません。 メッセージングなどの Quarkus アプリケーションへの他の「エントリーポイント」もサポートされていません。
さらに、負荷制限の実装は現時点ではかなり基本的なものであり、実稼働環境で十分にテストされていません。 改善が必要になる可能性があります。
4. 設定リファレンス
ビルド時に固定された設定プロパティー。その他の設定プロパティーはすべて実行時にオーバーライド可能です。
Configuration property |
タイプ |
デフォルト |
|---|---|---|
Whether load shedding should be enabled. Currently, this only applies to incoming HTTP requests. Environment variable: Show more |
ブーリアン |
|
The maximum number of concurrent requests allowed. Environment variable: Show more |
int |
|
The Environment variable: Show more |
int |
|
The Environment variable: Show more |
int |
|
The probe factor of the Vegas overload detection algorithm. Environment variable: Show more |
double |
|
The initial limit of concurrent requests allowed. Environment variable: Show more |
int |
|
Whether priority load shedding should be enabled. Environment variable: Show more |
ブーリアン |
|
5. さらに詳しく
Netflix Technology ブログ:
Uber Engineering ブログ:
Amazon Builders' Library:
Google Cloud ブログ:
CodeReliant ブログ:
TCP Vegas:
-
TCP Congestion Control: A Systems Approach、 Chapter 5: Avoidance-Based Algorithms