istio トラフィック管理の課題の探求 -- [接続プール (サーキット ブレーカー)] と [異常値の検出]

目次

前に書く

ビジネスニーズのため、技術アーキテクチャをアップグレードし、比較検討を重ねた結果、最終的に最先端の技術フレームワークであるservicemeshを選択しました...その代表的なものの1つがistioです。ピットに入ってみて分かったのは、中国ではこのことに関する情報が本当に少ないということです。公式文書ではさまざまな構成が紹介されていますが、そのほとんどは数筆で簡単に言及されています。実際に製品で使用されると、、その実装メカニズムを自分で常に調査する必要があります。そうしないと、このパラメータがなぜこのように設定されているのか、この設定がビジネス シナリオに適切であるかどうかがわかりません。

istio はオープンソースのフレームワークではありますが、運用保守の立場である私はコードを深く理解しているわけではなく、多くの巨匠のようにコードを勉強して本質を直接分析することはできませんので、「真実」を見つけることしかできません。この記事は、istio を使用する過程で遭遇したさまざまな疑問を記録するものであり、実際に検証されたものもあれば、具体的な結果がなく、今後の作業や研究で継続的に検討する必要があるものも含まれます。

この記事は、新しい問題の追加、古い問題の解決、または古い問題の更新のために継続的に更新されます。

名詞の定義

サービスレベル

注意:以下设定仅是本文为方便描述自行定义。

  • 第 1 レベルのサービス: この記事では、ingressgateway ポートによって直接マップされ、クラスターの外部から直接呼び出すことができるサービスを指します。

  • 第 2 レベルのサービス: 第 1 レベルのサービス、第 3 レベルおよび第 4 レベルのサービスなどによって呼び出されるサービス。

注: ここでのサービス レベルは相対的なものであり、絶対的なものではありません。その目的は、各サービス間の呼び出し関係のその後の説明を容易にすることです。たとえば、3 つのサービス A\B\C があり、A サービスが Ingressgateway をマップし、A が B を呼び出し、B が C を呼び出す場合、A が第 1 レベルのサービス、B が第 2 レベルのサービス、C が第 3 レベルのサービスになります。 -レベルのサービス。Ingressgateway もマップする D があり、D が C を呼び出す場合、C がセカンダリ サービスになります。


交通政策関連

質問 1: 第 1 レベルのサービスは削除されますか? そうでない場合、第 1 レベルのサービスが失敗した場合はどうなりますか? 早く失敗する方法はありますか?

答え: (推測された答え)

以下仅为推论,我还没有实际证据证明,希望有同学了解的,给一个准确答案:

1. ダウンストリーム サービス (イングレスゲートウェイが含まれていない場合) がなく、その上で受動的な異常値検出を実行するサービスもありません。ヘルス チェックの問題が原因でない限り、インスタンスは削除されるべきではありませんが、ヘルス チェックの問題が原因ではありません。チェックの問題は引き続き発生します。追放されます。

2. 第 1 レベルのサービスはクラスターの外部で直接呼び出されるサービスであるため、それを外部から呼び出すサービス (ま​​たはクライアント) は、タイムアウト、再試行などの対応するポリシーを設定する必要があります。クライアントの場合は、これを設定する必要があります。リクエストが失敗した場合の動作(表示の問題など)も設定します。


質問 2: セカンダリ サービスおよびポストセカンダリ サービス用に接続プールを設定する必要がありますか? 接続プールが設定されている場合、異常値検出が構成されている場合に上流サービス接続プールがオーバーフローするため、下流サービスは削除されますか?

答え: (質問 8 を参照してください)


質問 3: セカンダリ以降のサービス用に接続プールが設定されていない場合、これらのセカンダリ サービスを大規模なトラフィックの影響からどのように保護する必要がありますか? envoyfilter によるレート制限ですか?

答え: (質問 8 を参照してください)

envoyfilter进行限速是可行的,但是在生产中如何应用,需要持续探索


質問4: HTTP/2の場合、connectionPoolの制限は有効になりますか? HTTP/2 がインスタンスごとに 2 つの接続を確立するのはなぜですか?

ここに画像の説明を挿入します

答え:

HTTP/2 を使用する場合、connectionPool は無意味であるはずです。通常、HTTP/2 の 2 つのインスタンス間のリンクは 1 つだけであるため、多少の設定は HTTP/2 に影響しません。公式ドキュメントは比較的明確です:
ここに画像の説明を挿入します
ただし、HTTP/2 を使用すると 2 つのリンクが作成されることがわかります。インターネットで情報を探しました。

Istio プロキシは、HTTP/2 経由で通信するときに 2 つの TCP 接続を確立します。これは、Istio プロキシが 2 つの TCP 接続を多重化する必要があるためです。TCP 接続の 1 つは制御フローに使用され、もう 1 つの TCP 接続はデータ フローに使用されます。制御ストリーム上のフレームはメッセージ フローを制御するために使用され、データ ストリーム上のフレームには実際の要求データと応答データが含まれます。

注:通信プロトコルについてはあまり詳しくないので、間違いがあればご指摘ください。


質問 5: アップストリーム サービスのサーキット ブレーカーはどのように実装されていますか?

答え:

  • http/1.1 プロトコルでは、アップストリーム サービスは宛先ルールで connectionPool を構成し、各ダウンストリーム インスタンスからアップストリーム クラスターへの TCP 接続の最大数を tcp.maxConnections で設定します。

例証します:

ダウンストリーム サービスの各インスタンスとアップストリーム サービスのクラスター間の TCP 接続の最大数。つまり、ダウンストリーム サービスに 3 つのインスタンスがあり、アップストリーム サービスにも 3 つのインスタンスがあり、アップストリーム サービスが最大接続数を設定する場合100 にすると、ダウンストリーム サービスのインスタンス 1 はアップストリーム サービスと同じになります。サービスの 2 つのインスタンス間の接続数の最大合計は 100 です。ダウンストリーム サービスのインスタンス 2 間の最大接続数の合計は 100 です。アップストリーム サービスも 100 です。インスタンス 3 にも同じことが当てはまります。

ダウンストリーム クラスターとアップストリーム クラスター間の接続の最大数は 100 であると言うのではありません。このコントロールの値は、次の例に示すように、istio-proxy の 15000/stat の Remaining_cx でクエリできます。
ここに画像の説明を挿入します

確認する:

httpbin は最大接続数を 10 に設定します
ここに画像の説明を挿入します

ここには 2 つの fortio インスタンスがあります。
注意看访问的映射端口是不同的,一个是15000,一个是25000

ここに画像の説明を挿入します
ここに画像の説明を挿入します
可以看到每个都是显示剩余10个连接。

次に、httpbin を見てください。15006 からの各接続は 0 です (結果をより明確に表示するために、fortio のみが httpbin を呼び出しているため、15006 の接続を直接フィルターするだけです)。
ここに画像の説明を挿入します
ここに画像の説明を挿入します

  • 最初のステップは、fortio から呼び出しを開始することです:
    ここに画像の説明を挿入します
    10 個の同時実行が直接開始されます。より長く継続するために、2000000 リクエストを送信します。この時点の Remaining_cx 値は 0 になっていることがわかりますが、別のポッドの Remaining_cx
    ここに画像の説明を挿入します
    は変更されました。値はまだ 10 です
    ここに画像の説明を挿入します
    。3 つの httpbin の接続数を見てください。3 つのポッドの合計は 10 です。この時点で、同時実行数が増加し、それらの合計も 10 になります。
    ここに画像の説明を挿入します
  • 次に、別のポッドを開始すると、httpbin へのリクエスト接続の合計は
    ここに画像の説明を挿入します
    すでに 20 になっています。

ここに画像の説明を挿入します

  • では、単一の httpbin インスタンスは設定された 10 接続を超えるでしょうか? fortio を 3 インスタンス、httpbin を 2 インスタンスに変更してテストしてみます。
    ここに画像の説明を挿入します
    明らかに、1 つのインスタンスでは設定された最大接続数を超えます。これは、TCP 接続の最大接続数が制限されていることを側面から証明することにもなります。接続数は、ダウンストリーム サービスの単一インスタンスとアップストリーム サービス クラスターの間。

  • http/1.1 プロトコルでは、maxRequestsPerConnection の設定に関して、http プロトコルを理解している学生は何が起こっているのかを理解する必要があります。長いリンク状態であっても、http/1.1 は一度に 1 つのリクエストしか送信できず、別のリクエストを開始することはありません。要求が返されるまで要求し、要求の最大数に達すると、接続が閉じられ、新しい接続が確立されます。このようにして、誰もが istio 設定におけるこのパラメータの役割を理解できるようになります。
    ここに画像の説明を挿入します

  • http1MaxPendingRequests については特に言うことはありません。キューを待機しているだけであり、http/1.1 と http2 の両方に有効です。

    これに基づいて、最大接続数とアップストリーム サービスとダウンストリーム サービスのインスタンス数の関係を簡単に推測できます。

    私は数学のレベルが半分しかなく、導出が間違っています。修正してください。

B服务单个实例可承受最大链接数a,B服务设置最大连接数x,共有y个实例
A服务作为下游服务,共计b个实例,每个实例到B服务都可以发起x个链接,所以B服务共可以发起xb个链接
要使B服务不会过载,则应该满足:xb/y<=x<=a
当x=a时:
b/y<=1
b<=y
当x<a时:
b/y<a/x
由此可知:b<=ay/x

ここに画像の説明を挿入します
これは単純な導出に過ぎず、実際の状況はこれよりもはるかに複雑であり、実際の状況に基づいて具体的な計算を行う必要があります。


質問 6: 接続プールのサイズは、現在のフローを制限するように設定されていますか?

答え:

接続プール サイズの設定と現在の制限の間には一定の関係がありますが、それらは同じではありません。

接続プール サイズは、他のサービスとの間で確立および維持される接続の数を制限するように設定されているため、接続の過負荷やリソースの浪費を回避しながら、アプリケーションのパフォーマンスと安定性を最適化できます。

電流制限は、1 秒あたりに処理できるリクエストの数を制限することで、アプリケーションのトラフィックとリクエストの負荷を制限します。Istio では、ルールベースのクォータ設定を通じて電流制限を実現できます。

2 つの違いは、接続プール サイズが確立および維持される接続の数に設定されるのに対し、現在の制限は 1 秒あたりに処理できるリクエストの数に設定されることです。接続プール サイズの設定によりアプリケーション トラフィックをある程度制御できますが、電流制限を直接実装するものではありません。

要約すると、接続プール サイズの設定と電流制限はどちらもアプリケーションのパフォーマンスと安定性を最適化する手段ですが、概念と実装方法は 2 つ異なります。


質問 7: グリッド ポッド内で、アプリケーションのサイドカーへのリンクとサイドカーのアップストリーム サービスへのリンクの間にはどのような関係がありますか?

答え:

  • HTTP/2 の場合は、何も言うことはありません。すべてが 1 つの長いリンクです。
  • アプリケーションが HTTP/1.1 を使用する場合、特に設定されていない限り、サイドカーはデフォルトでアップストリームに HTTP/1.1 を使用します。envoyはHTTP/1.1とHTTP/2間の変換をサポートしていますが、istioではHTTP/1.1とHTTP/2を強制的に変換すると、HTTP/2の送信処理時などに安定性や精度等に影響を及ぼす可能性があると考えております。パケットが失われると、HTTP/1.1 側で問題が発生しやすくなります。これに関連して、envoy のもう 1 つの機能を紹介すると、envoy 自体は上流リンクと下流リンクが分離されているため、HTTP/1.1 と HTTP/2 を変換できます。上流リンクと下流リンクの間には避けられない関係はありません。ただし、間接的な正の相関は依然として存在しており、結局、下流のリンクとリクエストが増加し、接続プールの範囲内では上流のリンクとリクエストも増加します。

bookinfo の例を使用して説明しましょう:
ここに画像の説明を挿入します
ここに画像の説明を挿入します
アップストリームとダウンストリームは相対的なものです。サイドカーの観点からリンクを見ると、アウトバウンド トラフィックの場合、そのダウンストリームは同じポッド内のアプリケーションであり、アップストリームはターゲット クラスターです。インバウンド トラフィックの場合は、まさにその逆です。

アウトバウンドかインバウンドかに関係なく、サイドカーは上流リンクと下流リンクから切り離されています。言い換えれば、アップストリーム リンクとダウンストリーム リンクのライフ サイクルは一貫していません。たとえば、HTTP/1.1 を使用する場合、アップストリームには 100 のリンクがあり、ダウンストリームには 50 のリンクがある可能性があります。別の例として、アウトバウンドの場合、ダウンストリームは HTTP です。 /1.1. 構成 h2UpgradePolicy: UPGRADE では、アップストリームは HTTP/2 です。


質問 8: 接続プールがオーバーフローしてサーキット ブレーカーが発生した後、ダウンストリーム サービスは 503 を受け取ります。この 503 を返すのは誰ですか?

答え:

現在のサービスのサイドカーによって返される 503。

istio ではコネクションプールが枯渇した場合、再度リクエストを送信するとオーバーフローサーキットブレーカーが発生するため、Envoyからは 503 が返されます。これは、Envoy がアップストリーム サービスへの接続をキャッシュするためです。アップストリーム サービスへの接続が失敗するか閉じられると、Envoy はこれらの接続を通じてリクエストを送信しようとし、接続がリセットされます。その後、Envoy はこのエラーを 503 にカプセル化して返します。下流の呼び出し元に。

分析:
ここに画像の説明を挿入します
まず、503 エラーが発生すると、リクエスト イニシエーターの fortio サイドカーにのみ大量の 503 エラーが発生するのに対し、httpbin のサイドカーには 200 個しかないことがわかります。

fortio のリターン ログを見てみましょう。503 UO upstream_reset_before_response_started{overflow}

このエラーは、アップストリーム サービスの接続プールがオーバーフローし、リクエストがリセットされたことを示します。UO は Envoy の応答フラグで、サーキット ブレークを伴うアップストリーム オーバーフローを意味します。これは、アップストリーム サービスへの接続数がヒューズのしきい値を超えていることを意味します。オーバーフローは Envoy のリセット タイプで、接続プールが使い果たされたことを示します。上で分析したように、接続プールのカウンターはダウンストリーム サービスのサイドカーにありますが、この 503 は fortio のサイドカー自体によって生成されるステータス コードである必要があることもここで間接的に述べられています。

これは envoy のドキュメントにも記載されています。

ここに画像の説明を挿入します
上記の観点から、503 ステータス コードは上流サービスから返されるのではなく、接続プールのオーバーフローに基づいて判断された上で、現在のサービスのサイドカーが自動的に生成され、下流アプリケーションに返されると考えられます。つまり、このエラーはロード バランシングの前に発生し、Envoy はアップストリーム サービス インスタンスを選択する前に接続数がサーキット ブレーカーのしきい値に達したことを検出したため、ロード バランシングを実行せずにリクエストを直接拒否しました。

同時に、複数のテスト中に、外れ値検出がトリガーされることは見つかりませんでした。これは、返されたサービスがアップストリーム サービスであるべきではないことも証明しています。これは、接続プールのオーバーフローが異常値の検出をトリガーしないことを証明しているように見えます。

ここに画像の説明を挿入します
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/Mrheiiow/article/details/130411303
おすすめ