静的サーキットブレーカーでは、各サービスごとに固定の同時実行数しきい値を推定し、手動で設定する必要があります。この推定値が低すぎると正当なトラフィックがブロックされ、高すぎるとサーキットブレーカーが作動する前にサービスが過負荷状態になります。ASMAdaptiveConcurrency カスタムリソース定義 (CRD) は、リアルタイムのレイテンシ測定に基づいて同時実行数の上限を動的に調整することで、このような推定作業を不要にし、手動チューニングなしでサービスの実際の処理能力に近い上限値を維持します。
同時リクエスト数が計算された上限値を超えると、サイドカープロキシは HTTP ステータスコード 503 およびエラーメッセージ reached concurrency limit を返します。
仕組み
適応型同時実行制御コントローラーは、勾配ベースのアルゴリズムを使用して、サービスのベースラインレイテンシ(MinRTT)を定期的に測定し、サンプリングされたリクエストのレイテンシ(SampleRTT)と比較して、同時実行数の上限値を調整します。
勾配の計算
コントローラーは、サンプリングされたレイテンシから以下の式で勾配値を計算します。
gradient = (minRTT + buffer) / sampleRTTバッファーは通常のレイテンシ分散を吸収するため、サンプリングされたレイテンシがベースラインを有意に上回った場合にのみ勾配が低下します。
buffer = minRTT * buffer_pctその後、この勾配を使って同時実行数の上限値が更新されます。
new_limit = gradient * current_limit + headroomサービスが正常な状態では、sampleRTT は minRTT に近い値を維持し、勾配は 1.0 近辺で安定するため、上限値も安定または増加します。一方、サービスが過負荷になると sampleRTT が上昇し、勾配が 1.0 未満に低下して上限値が減少します。これにより、サービスの状態がさらに悪化する前に超過分のリクエストが拒否されます。
MinRTT の再計算
コントローラーは、同時実行数の上限を一時的に min_concurrency 値まで下げることで、定期的に MinRTT を再計算します。この期間中は、ごく少数のリクエストのみが転送されるため、サービスは真の最小レイテンシで応答できます。
MinRTT 再計算中は同時実行数の上限が大幅に低下するため、HTTP 503 応答が一時的に急増する可能性があります。これを軽減するには、対象サービスに対してリトライを有効にする宛先ルールを作成してください。これにより、サイドカープロキシは MinRTT 再計算ウィンドウにない他のホストに対して拒否されたリクエストを再試行できます。
前提条件
作業を開始する前に、以下の要件を満たしていることを確認してください。
バージョン 1.12.4.19 以降の Service Mesh (ASM) インスタンス。詳細については、「ASM インスタンスの作成」をご参照ください。
ASM インスタンスに追加されたクラスター。詳細については、「ASM インスタンスにクラスターを追加する」をご参照ください。
クラスターに接続された kubectl クライアント。 詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。
ステップ 1:サンプルアプリケーションのデプロイ
本チュートリアルでは、適応型同時実行制御をデモンストレーションするために、以下の 2 つのアプリケーションを使用します。
| アプリケーション | 役割 | 構成 |
|---|---|---|
| testserver | 対象サービス | 最大 500 の同時リクエストを処理可能。各リクエストの処理時間は 1,000 ms。同時実行数の上限を超えたリクエストはキューイングされます。 |
| gotest | 負荷生成ツール | 各レプリカが testserver に対して 200 の同時リクエストを送信します。 |
testserver のデプロイ
以下の内容で
testserver.yamlという名前のファイルを作成します。-mフラグは最大同時リクエスト数(500)を設定します。-tフラグは各リクエストの処理時間をミリ秒単位(1,000)で設定します。デプロイメントを適用します。
kubectl apply -f testserver.yaml
testserver サービスの作成
以下の内容で
testservice.yamlという名前のファイルを作成します。サービスを適用します。
kubectl apply -f testservice.yaml
gotest のデプロイ
以下の内容で
gotest.yamlという名前のファイルを作成します。初期レプリカ数は 0 に設定されています。ステップ 4 で負荷を生成するためにスケールアップします。
デプロイメントを適用します。
kubectl apply -f gotest.yaml
ステップ 2:ASMAdaptiveConcurrency CRD の作成
kubectl をご利用の ASM インスタンスに接続します。詳細については、「コントロールプレーン上の kubectl を使用した Istio リソースへのアクセス」をご参照ください。
以下の内容で
adaptiveconcurrency.yamlという名前のファイルを作成します。apiVersion: istio.alibabacloud.com/v1beta1 kind: ASMAdaptiveConcurrency metadata: name: sample-adaptive-concurrency namespace: default spec: workload_selector: labels: app: testserver sample_aggregate_percentile: value: 60 concurrency_limit_params: max_concurrency_limit: 500 concurrency_update_interval: 15s min_rtt_calc_params: interval: 60s request_count: 100 jitter: value: 15 min_concurrency: 50 buffer: value: 25この構成の意味は以下のとおりです。
testserverワークロードを対象とし、同時リクエスト数の上限を 500 に設定します。サンプリングされたレイテンシの 60 パーセンタイルを SampleRTT として使用し、15 秒ごとに同時実行数の上限を更新します。
MinRTT を 60 秒ごと(最大 15% のランダムジッター付き)に再計算し、その際に 100 件のサンプリングリクエストを使用します。MinRTT 再計算中は、同時実行数を 50 リクエストに制限します。
MinRTT の 25% 以内のレイテンシ変動は正常範囲と見なします。
CRD を適用します。
kubectl apply -f adaptiveconcurrency.yaml
パラメーター リファレンス
| パラメーター | タイプ | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
workload_selector | WorkloadSelector | はい | -- | ラベルで対象の Pod を選択します。 |
labels | map | はい | -- | 対象の Pod と一致させるラベルです。 |
sample_aggregate_percentile | Percent | はい | -- | サンプリングされたレイテンシを集約して SampleRTT を算出する際に使用するパーセンタイルです。有効値:0 ~ 100。 |
concurrency_limit_params | Object | はい | -- | 同時実行数の上限に関する設定です。 |
max_concurrency_limit | int | いいえ | 1000 | 同時リクエスト数の上限値です。 |
concurrency_update_interval | duration | はい | -- | コントローラーが同時実行数の上限を更新する間隔です。例:60s。 |
min_rtt_calc_params | Object | はい | -- | MinRTT 計算に関する設定です。 |
interval | duration | いいえ | -- | MinRTT を再計算する間隔です。例:120s。 |
request_count | int | いいえ | 50 | MinRTT 計算のためにサンプリングするリクエスト数です。 |
jitter | Percent | いいえ | 15 | MinRTT 再計算間隔に追加されるランダムジッターです。例えば、interval が 120s、jitter が 50 の場合、実際の間隔は random(120, 120 + 120 * 50%) 秒となります。 |
min_concurrency | int | いいえ | 3 | MinRTT 再計算中の同時実行数の上限です。また、コントローラー起動時の初期上限値としても使用されます。正確なベースライン測定を行うため、サービスの実際の処理能力よりも十分に低い値に設定してください。 |
buffer | Percent | いいえ | 25 | MinRTT に対する許容レイテンシ変動の割合(パーセント)です。例えば、MinRTT が 100 ms、buffer が 10 の場合、110 ms までのレイテンシは正常と見なされます。 |
ステップ 3:Prometheus によるモニタリングの設定
Managed Service for Prometheus に適応型同時実行制御のメトリックをエクスポートし、コントローラーの動作を観測してパラメーターをチューニングします。
ご利用のクラスターに対して Managed Service for Prometheus を有効化します。詳細については、「Managed Service for Prometheus の使用」をご参照ください。
testserver のサイドカープロキシからメトリックをスクレイプするための ServiceMonitor を作成します。
以下の内容で
servicemonitor.yamlという名前のファイルを作成します。apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: testserver-envoy-metrics namespace: default spec: endpoints: - interval: 5s path: /stats/prometheus port: metrics namespaceSelector: any: true selector: matchLabels: app: testserverkubectl を ACK クラスターに接続し、ServiceMonitor を適用します。
kubectl apply -f servicemonitor.yaml
コントローラーメトリックを可視化するための Grafana ダッシュボードをインポートします。ダッシュボードの JSON ファイルをダウンロードし、Managed Service for Grafana コンソールでインポートしてください。インポート手順の詳細については、「ARMS ドキュメント」をご参照ください。
ステップ 4:同時実行制御コントローラーの検証
testserver に対して負荷をかけ、ASMAdaptiveConcurrency CRD が期待通りに同時実行数を制限することを確認します。
gotest デプロイメントを 5 レプリカにスケールします。各レプリカが 200 の同時リクエストを送信するため、合計で 1,000 の同時リクエストが生成され、testserver の処理能力(500 リクエスト)の 2 倍になります。
ACK コンソール にログインします。左側のナビゲーションウィンドウで、クラスター をクリックします。
クラスター ページで、ご利用のクラスターを見つけ、その名前をクリックするか、操作 列の 詳細 をクリックします。
左側のナビゲーションウィンドウで、ワークロード > デプロイメント を選択します。
デプロイメント ページで、名前空間 を default に設定します。gotest アプリケーションの 操作 列で、その他 > YAML で表示 を選択します。
YAML の編集 ダイアログボックスで、
replicasを5に設定し、更新 をクリックします。
ステップ 3 でインポートした Grafana ダッシュボードを開きます。サービス を
testserver、Pod をALLに設定します。ConcurrencyLimit パネルを確認します。同時実行数の上限が 500 未満で安定していることを確認し、コントローラーが testserver を過負荷から保護していることを検証します。RqBlocked パネルには、拒否されたリクエストの累積数が表示されます。
メトリック リファレンス
適応型同時実行制御コントローラーは、以下の Prometheus メトリックをサイドカープロキシ経由で公開します。これらのメトリックを使用してコントローラーの動作を監視し、CRD パラメーターをチューニングできます。
| メトリック | タイプ | 説明 |
|---|---|---|
rq_blocked | Counter | 同時実行制御コントローラーによって拒否されたリクエストの総数です。 |
burst_queue_size | Gauge | 同時実行数の上限計算に使用される現在のヘッドルーム値です。 |
concurrency_limit | Gauge | コントローラーによって適用されている現在の同時実行数の上限です。 |
gradient | Gauge | 現在の勾配値です。 |
min_rtt_msecs | Gauge | ミリ秒単位の現在の MinRTT 測定値です。 |
sample_rtt_msecs | Gauge | ミリ秒単位の現在の SampleRTT 集計値です。 |
min_rtt_calculation_active | Gauge | コントローラーが MinRTT を再計算しているときに 1 に設定されます。 |
すべてのメトリックには、envoy_http_inbound_0_0_0_0_8080_adaptive_concurrency_gradient_controller_ という名前空間プレフィックスが付与されます。
本番環境に適用
リトライを有効化する:MinRTT 再計算ウィンドウ中に発生する 503 応答を処理するため、対象サービスに対してリトライポリシーを含む宛先ルールを作成します。
パラメーターをチューニングする:Grafana ダッシュボードの観測結果に基づき、
concurrency_update_interval、min_concurrency、bufferを調整します。bufferを小さくするとコントローラーはレイテンシ変化に対してより敏感になり、大きくするとより多くの変動を許容します。自社のワークロードに適用する:
workload_selectorのラベルを自社の本番ワークロードを指すように変更します。保守的な設定(min_concurrencyを想定処理能力よりも十分に低く設定)から始め、メトリックに基づいて段階的に調整してください。