このトピックでは、トラフィック スケジューリング スイートによって提供される ConcurrencySchedulingPolicy を使用して、制御された同時実行下で優先順位に基づくリクエスト スケジューリングを実装する方法について説明します。
背景情報
ConcurrencySchedulingPolicy は、同時リクエストの制限に基づいてトラフィックが過負荷になっているかどうかを判断します。同時リクエスト数が指定された上限を超えると、後続のリクエストはキューに入れられ、優先順位に基づいてスケジュールされます。ConcurrencySchedulingPolicy は次の方法で動作します。
ConcurrencySchedulingPolicy は、同時実行リミッターを使用して、処理中の同時リクエスト数を記録し、同時リクエスト数が上限に達しているかどうかを判断します。
同時リクエスト数が上限に達すると、後続のリクエストはキューに入れられ、前のリクエストが処理された後に宛先サービスに送信されます。これにより、特定の数の同時リクエストが維持されます。さらに、優先順位の高いリクエストは、キューから取り出されて宛先サービスに送信される可能性が高くなります。
同時リクエスト数がシステムで処理できるリクエストの上限を超えた場合、ConcurrencySchedulingPolicy はリクエストを直接拒否するのではなく、優先順位キューに入れます。これは、指定されたしきい値に達したときにリクエストを拒否する ConcurrencyLimitingPolicy とは異なります。ConcurrencySchedulingPolicy は、同時リクエスト数が上限内にあることを保証しながら、優先順位に基づいてリクエストをスケジュールします。
前提条件
Container Service for Kubernetes(ACK)マネージド クラスタが Service Mesh(ASM)インスタンスに追加されており、ASM インスタンスのバージョンが V1.21.6.97 以降であること。詳細については、「ASM インスタンスへのクラスタの追加」をご参照ください。
ACK クラスタのデフォルトの名前空間で、自動サイドカー プロキシ インジェクションが有効になっていること。詳細については、「グローバル名前空間の管理」をご参照ください。
kubectl を使用して ACK クラスタに接続していること。詳細については、「クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続する」をご参照ください。
ASM トラフィック スケジューリング スイートが有効になっていること。詳細については、「ASM トラフィック スケジューリング スイートを有効にする」をご参照ください。
HTTPBin アプリケーションがデプロイされており、ASMイングレス ゲートウェイを使用してアクセスできること。詳細については、「HTTPBin アプリケーションをデプロイする」をご参照ください。
手順 1:ConcurrencySchedulingPolicy を作成する
kubectl を使用して ASM インスタンスに接続します。詳細については、「コントロール プレーンで kubectl を使用して Istio リソースにアクセスする」をご参照ください。
次の内容を含む concurrencyschedulingpoilcy.yaml ファイルを作成します。
apiVersion: istio.alibabacloud.com/v1 kind: ConcurrencySchedulingPolicy metadata: name: concurrencyscheduling namespace: istio-system spec: concurrency_scheduler: max_concurrency: 10 concurrency_limiter: max_inflight_duration: 60s scheduler: workloads: - label_matcher: match_labels: http.request.header.user_type: guest parameters: priority: 50.0 name: guest - label_matcher: match_labels: http.request.header.user_type: subscriber parameters: priority: 200.0 name: subscriber selectors: - service: httpbin.default.svc.cluster.local次の表に、いくつかのパラメータを示します。構成項目の詳細については、「ConcurrencySchedulingPolicy フィールドの説明」をご参照ください。
フィールド
説明
max_concurrency
同時リクエストの最大数。この例では、このフィールドは 10 に設定されています。これは、サービスが一度に 10 個のリクエストを処理できることを示しています。
max_inflight_duration
リクエスト処理のタイムアウト期間。クラスタ内のポッドの再起動などの予期しないイベントが原因で、ASM トラフィック スケジューリング スイートがリクエスト終了イベントの記録に失敗する可能性があります。このようなリクエストが同時実行制限アルゴリズムの判断に影響を与えるのを防ぐため、リクエスト処理のタイムアウト期間を指定する必要があります。このタイムアウト期間の前にリクエストが応答されていない場合、システムはそのようなリクエストが処理されたと見なします。リクエストの予想される最大応答時間を評価することで、このフィールドを設定できます。この例では、このフィールドは 60 秒に設定されています。
workloads
リクエスト ヘッダーの user_type に基づいて、2 種類のリクエスト(guest と subscriber)が定義されます。guest タイプのリクエストの優先度は 50 で、subscriber タイプのリクエストの優先度は 200 です。
selectors
調整ポリシーが適用されるサービス。この例では、service: httpbin.default.svc.cluster.local が使用されています。これは、同時実行制限ポリシーが httpbin.default.svc.cluster.local サービスに適用されることを示しています。
次のコマンドを実行して、ConcurrencySchedulingPolicy を作成します。
kubectl apply -f concurrencyschedulingpoilcy.yaml
手順 2:同時リクエストが制御されているシナリオで、優先順位に基づくリクエスト スケジューリングの結果を確認する
この例では、ストレステスト ツールである Fortio を使用します。詳細については、GitHub Web サイトの Fortio の「インストール」セクションをご参照ください。
2 つのターミナルを開き、同時に次の 2 つのストレステスト コマンドを実行して、テストを開始します。テスト全体を通して、2 つのターミナルが予期どおりに動作していることを確認してください。2 つのターミナルでのテストでは、10 個の同時リクエストがサービスに送信され、1 秒あたりのクエリ数(QPS)は 10,000 です。これは、サービスが耐えられる同時リクエスト数を大幅に超えています。
fortio load -c 10 -qps 10000 -H "user_type:guest" -t 30s -timeout 60s -a http://${ASMイングレス ゲートウェイの IP アドレス}/status/201fortio load -c 10 -qps 10000 -H "user_type:subscriber" -t 30s -timeout 60s -a http://${ASMイングレス ゲートウェイの IP アドレス}/status/202説明上記のコマンドの
${ASM ゲートウェイの IP アドレス}を、ASMイングレス ゲートウェイの IP アドレスに置き換えます。ASMイングレス ゲートウェイの IP アドレスを取得する方法の詳細については、「Istio リソースを使用してトラフィックをサービスの異なるバージョンにルーティングする」トピックの手順 3 のサブステップ 1 をご参照ください。テスト 1 からの予期される出力:
... # target 50% 4.35294 # target 75% 5.39689 # target 90% 5.89697 # target 99% 6.19701 # target 99.9% 6.22702 Sockets used: 10 (for perfect keepalive, would be 10) Uniform: false, Jitter: false Code 201 : 84 (100.0 %) Response Header Sizes : count 84 avg 249.88095 +/- 0.3587 min 248 max 250 sum 20990 Response Body/Total Sizes : count 84 avg 249.88095 +/- 0.3587 min 248 max 250 sum 20990 All done 84 calls (plus 10 warmup) 3802.559 ms avg, 2.6 qps Successfully wrote 5186 bytes of Json data to xxxxxx.jsonテスト 1 によって出力された JSON ファイルの名前(例:xxxxxx.json)を記録します。
テスト 2 からの予期される出力:
... # target 50% 1.18121 # target 75% 1.63423 # target 90% 1.90604 # target 99% 2.22941 # target 99.9% 2.28353 Sockets used: 10 (for perfect keepalive, would be 10) Uniform: false, Jitter: false Code 202 : 270 (100.0 %) Response Header Sizes : count 270 avg 250.52963 +/- 0.5418 min 249 max 251 sum 67643 Response Body/Total Sizes : count 270 avg 250.52963 +/- 0.5418 min 249 max 251 sum 67643 All done 270 calls (plus 10 warmup) 1117.614 ms avg, 8.8 qps Successfully wrote 5305 bytes of Json data to yyyyyy.jsonテスト 2 によって出力された JSON ファイルの名前(例:yyyyyy.json)を記録します。
上記の出力は、テスト 2 の平均リクエスト レイテンシがテスト 1 の約 4 分の 1 であり、QPS がテスト 1 の約 4 倍であることを示しています。これは、以前に定義されたポリシーでは、subscriber タイプのリクエストの優先度が guest タイプのリクエストの 4 倍であるためです。
(オプション)結果を視覚的に表示します。
前の手順で 2 つのコマンドを実行したオンプレミス ディレクトリで次のコマンドを実行して、ローカル Fortio サーバーを開きます。
fortio serverブラウザを使用して
http://localhost:8080/fortio/browseにアクセスし、サブステップ 1 で記録した対応する JSON ファイルの名前をクリックして、視覚化されたテスト結果を表示します。テスト 1 の視覚化された結果の例:

テスト 2 の視覚化された結果の例:

上記の視覚化された結果は、少数の無制限のリクエストを除いて、ほとんどの guest タイプのリクエストのレイテンシが 4,000 ~ 6,000 ms であることを示しています。ただし、ほとんどの subscriber タイプのリクエストのレイテンシは 1,000 ~ 2,000 ms です。サービスへのリクエストが上限を超えると、subscriber タイプのリクエストが最初に応答されます。さらに、サービスに送信される同時リクエストは特定の値に制限されます。
参考資料
Grafana で ConcurrencySchedulingPolicy が有効になっているかどうかを確認できます。Grafana の Prometheus インスタンスが ASM トラフィック スケジューリング スイート で構成されていることを確認する必要があります。
次の内容を Grafana にインポートして、ConcurrencySchedulingPolicy のダッシュボードを作成できます。
ダッシュボードは次のとおりです。
