ホームページ >よくある問題 >電流制限と一般的な解決策を 10 分で理解します。

電流制限と一般的な解決策を 10 分で理解します。

Java后端技术全栈
Java后端技术全栈転載
2023-08-15 16:15:432025ブラウズ

最近、数人のネチズンからインタビューのフィードバックを受け取りましたが、インタビュー中に全員が 現在の制限 関連の質問をされました。今日は、私たちのプロジェクトにおけるさまざまな電流制限ソリューションについて話しましょう。

電流制限の基本概念

一般的な電流制限シナリオの場合、 2 つの次元 情報:

  • 制限時間は、特定の時間範囲または特定の時点に基づいています。これは、毎分、毎秒など、よく「タイム ウィンドウ」と呼ばれるものです。クロックの時間枠を制限する
  • リソースは、最大アクセス数や利用可能な接続の最大数の設定など、利用可能なリソースに基づいて制限されます

上 2 つの側面を組み合わせると、電流制限とは、1 秒あたり最大 100 アクセス リクエストを設定するなど、特定の時間枠内のリソース アクセスを制限することを意味します。しかし、実際のシナリオでは、1 つの電流制限ルールを設定するだけでなく、複数の電流制限ルールを設定して連携して動作させることもできます。主な電流制限ルールは次のとおりです:

QPS と接続数の制御

(接続数およびQPS)の電流制限については、IPディメンションで電流制限を設定することも、単一サーバーに基づいて電流制限を設定することもできます。

電流制限と一般的な解決策を 10 分で理解します。
写真

実際の環境では、通常、同じ IP のアクセス頻度を 10 未満に設定するなど、複数の次元での電流制限ルールが設定されます。接続数が 5 未満の場合は、各マシンの QPS を最大 1000 に設定し、接続数を最大 200 に保ちます。さらに、サーバグループや計算機室全体のサーバをまとめて、より上位の電流制限ルールを設定することもでき、これらの電流制限ルールが連携してトラフィック制御を行います。

通信速度

リソースのダウンロード速度など、「通信速度」については誰もがよく知っています。一部の Web サイトでは、この領域でより詳細な電流制限ロジックが用意されています。たとえば、一般の登録ユーザーのダウンロード速度は 100k/s、メンバーシップ購入後は 10M/s になります。この背後には、ユーザー グループに基づいた電流制限ロジックがあります。またはユーザータグ。

ブラック リストとホワイト リスト

ブラック リストとホワイト リストは、大規模なエンタープライズ アプリケーションでデータを制限および解放する非常に一般的な手段であり、多くの場合、ブラック リストとホワイト リストは動的に変更されます。たとえば、ある IP が一定期間にあまりにも頻繁にアクセスされ、ロボット ユーザーまたはトラフィック攻撃としてシステムによって識別された場合、その IP はブラックリストに追加され、それによってシステム リソースへのアクセスが制限されます。一般に「IP ブロッキング」として知られているもの。

私たちがよく目にするクローラー プログラム、たとえば、Zhihu で美しい女性の写真をクロールしたり、証券システムの株式のタイムシェアリング情報をクロールしたりする場合、これらのクローラー プログラムは、追加されないように IP を変更する機能を実装する必要があります。 。

会社のネットワークが 12306 などの大規模な公開 Web サイトにアクセスできない場合もあります。これは、一部の会社の送信 IP アドレスが同じアドレスであるためでもあります。そのため、アクセス数が多すぎると、この IP アドレスは相手のシステムによって認識され、ブラックリストに追加されます。家庭用ブロードバンドを使用する学生は、ほとんどのネットワーク オペレータがユーザーを異なる送信 IP セグメントに割り当てたり、ユーザーの IP アドレスを随時動的に変更したりしていることを知っておく必要があります。

ホワイトリストの方が分かりやすく、王室から授与される金メダルに相当し、様々な電流制限ルールを何の障害もなく自由に行き来することができます。たとえば、一部の電子商取引企業は、非常に大規模な販売者のアカウントをホワイトリストに追加します。そのような販売者は独自の運用および保守システムを持っていることが多く、大量の製品のリリースや補充を行うために企業の IT システムと接続する必要があるためです。 、など。さらに、パブリック アカウントのバックエンド Programming Technology Circle を検索し、「Java」と返信すると、サプライズ ギフト パッケージがプレゼントされます。

分散環境

分散は、単一マシンの電流制限シナリオとは異なり、分散環境全体のすべてのサーバーを全体として考慮します。たとえば、IP 電流制限の場合、1 つの IP を 1 秒あたり最大 10 アクセスに制限します。この IP からのリクエストがどのマシンに送信されるかに関係なく、クラスタ内のサービス ノードにアクセスする限り、この制限の対象となります。電流制限 ルールによる制約。

クラスター内のすべてのマシンのアクセス ステータスを取得できるように、電流制限情報を「集中型」コンポーネントに保存することをお勧めします。現在、主流の電流制限ソリューションは 2 つあります。

  • ゲートウェイ層電流制限は、すべてのトラフィックの入口に電流制限ルールを適用します。
  • ミドルウェア電流制限は、特定のミドルウェア内の分散型に電流制限情報を保存します。環境 (Redis キャッシュなど) では、各コンポーネントはここから現時点でのトラフィック統計を取得し、それによってサービスを拒否するかトラフィックを許可するかを決定できます
  • センチネル、コンポーネント テーラー- 分散型電流制限、サーキット ブレーカーの劣化、その他のコンポーネント用の Springcloud エコシステムによってマイクロサービス用に作成されました

電流制限スキームに一般的に使用されるアルゴリズム

トークン バケット アルゴリズム

トークン バケット トークン バケット アルゴリズムは、現在最も広く使用されている電流制限アルゴリズムです。名前が示すように、次の 2 つの重要な役割があります。

  • トークンは、リクエストがトークンを取得した後にのみ処理されます。他のリクエストはキューに入れられるか、直接破棄されます。
  • バケットが配置される場所トークンを保持するために使用され、すべてのリクエストはこのバケットからトークンを取得します。これには主に 2 つのプロセスが含まれます:
  • トークン生成

このプロセスには、トークン ジェネレーターとトークン バケットが含まれます。トークン バケットはトークンの場所であると前述しました。バケットであるため、容量が必要です。つまり、トークン バケットが多数のトークンを保持できることを意味します. カードの枚数は固定値です。

トークン ジェネレーターの場合、所定のレートに従ってバケットにトークンを追加します。たとえば、1 秒あたり 100 リクエスト、または 1 分あたり 50 リクエストのレートでトークンを発行するように構成できます。 。ここでの発行速度は均一であることに注意してください。これは、これらの 50 個のトークンが各時間ウィンドウの開始時に一度に発行されるのではなく、この時間ウィンドウ内で均一の速度で発行されることを意味します。

トークンディスペンサーは蛇口になっており、下の水を入れたバケツが満水になると自然に水(トークン)が外に流れ出ます。トークン発行時も同様で、トークンバケットの容量には限りがあり、定格容量のトークンがいっぱいになった場合、新しいトークンは破棄されます。

  • #トークンの取得
アクセス要求が到着するたびに、次の手順のロジックを実行するためにトークンを取得する必要があります。トークンの数が少なくアクセスリクエストが多い場合、当然トークンを取得できないリクエストも出てきますが、その際に余ったトークンを一時的に保管する「バッファキュー」を設けることができます。

バッファ キューは実際にはオプションのオプションであり、トークン バケット アルゴリズムを適用するすべてのプログラムがキューを実装するわけではありません。キャッシュ キューがある場合、トークンをまだ取得していないリクエストは、新しいトークンが生成されるまでこのキューに入れられ、トークンと一致するリクエストがキューの先頭から取得されます。

キューがいっぱいになると、アクセス要求のこの部分は破棄されます。実際のアプリケーションでは、キュー内のリクエストの生存時間を設定したり、キューを PriorityQueue に変換して、先入れ先出しではなく特定の優先順位に従って並べ替えたりするなど、一連の特殊効果をこのキューに追加することもできます。 。

リーキー バケット アルゴリズム

リーキー バケットは別のバケットであり、電流制限アルゴリズムはバケットに関連しています。では、リーキー バケットとトークン バケットの違いは何ですか?

リーキーバケットアルゴリズムの前半部分はトークンバケットと似ていますが、動作対象が異なり、トークンバケットはバケットにトークンを入れるのに対し、リーキーバケットはアクセス要求パケットをバケットに入れます。同様に、バケットがいっぱいの場合、受信パケットは破棄されます。

リーキーバケットアルゴリズムの後半には特徴があり、常に一定のレートでデータパケットがバケットから流出します。たとえば、100 個のデータ パケットを保存するようにリーキー バケットを設定し、流出速度が 1 秒あたり 1 の場合、データ パケットがバケットに流入する速度やバケット内にデータ パケットがいくつあるかに関係なく、リーキー バケットは、これらのデータ パケットが常に 1 秒の一定速度で処理されることを保証します。さらに、公式アカウントのバックエンドアーキテクトのバックエンドリプライ「クリーンアーキテクチャ」を検索すると、サプライズのギフトパッケージがプレゼントされます。

  • リーキーバケットとトークンバケットの違い

両方のアルゴリズムが持つそれぞれの特性に基づいて理解するのは難しくありません。 「一定」レートと「不定」レート。トークンバケットは一定のレートでトークンを生成しますが、アクセスリクエストがトークンを取得するレートは「不定」で、とにかくトークンがあればあるだけ発行され、トークンがなくなったらただ待つだけです。リーキー バケットはリクエストを「一定」のレートで処理しますが、これらのリクエストがバケットに流入するレートは「可変」です。

これら 2 つの特性から、リーキー バケットの自然な特性により、バースト トラフィックが発生しないことがわかります。たとえ 1 秒あたり 1,000 リクエストが到着したとしても、バックグラウンド サービス出力へのアクセス レートは常に一定です。トークンバケットは異なります。一定量のトークンを「事前に保存」できる機能があるため、突発的なトラフィックに対処する際に、短時間ですべてのトークンを消費できます。バーストトラフィックの処理効率はリーキーよりも高くなります。バックエンド システムへの負荷もそれに応じて増加します。

スライディング ウィンドウ

たとえば、1 秒ごとに 5 人のユーザーがアクセスし、5 秒以内に 10 人のユーザーがアクセスする場合、0 ~ 5 秒の時間ウィンドウ内にアクセスすることになります。金額は15です。インターフェイスが時間ウィンドウ内のアクセスの上限を 20 に設定すると、時間が 6 秒目に達すると、1 秒のグリッドが時間ウィンドウから出たため、この時間ウィンドウ内の合計カウントは 10 になります。 6 秒以内に受信できる訪問数は 20-10=10 です。

スライディング ウィンドウは実際には計算アルゴリズムであり、時間ウィンドウのスパンが長いほど電流制限効果がより滑らかになるという特徴があります。たとえば、現在のタイム ウィンドウが 2 秒しかなく、すべてのアクセス要求が最初の 1 秒に集中している場合、時間が 1 秒戻ると、現在のウィンドウのカウントが大幅に変化します。この出来事の状況

一般的に使用される電流制限スキーム

合法性検証電流制限

検証コード、IP ブラックリスト、など、これらの手段は悪意のある攻撃やクローラーの収集を効果的に防ぐことができます;

Guawa 電流制限

電流制限の分野では、Guava はマルチスレッド モジュールの下に次の # 機能を提供します。 ##RateLimiter で始まる電流制限サポート クラスですが、そのスコープは「現在の」サーバーに限定されています。言い換えれば、Guawa の電流制限は単一マシンの電流制限であり、複数のマシンまたは JVM プロセスにわたって何も行うことはできません。たとえば、現在 2 台のサーバー [サーバー 1, サーバー 2] があり、どちらのサーバーもログイン サービスをデプロイしています。これら 2 台のマシンでトラフィック制御を実行したい場合、 , たとえば、2 台のマシンの合計訪問数を 1 秒あたり 20 回以内に制御する場合、Guava を使用して行う場合、各マシンの訪問数を個別に制御できるのは 10 以下のみです。

Guava は分散システム用のソリューションではありませんが、シンプルで軽量のクライアント電流制限コンポーネントとして、電流制限アルゴリズムを説明するのに非常に適しています

ゲートウェイ層の電流制限

サービス ゲートウェイは、分散リンク全体の最初のレベルとして、すべてのユーザー要求を受け入れるため、ゲートウェイ レベルで電流を制限することが適切なエントリ ポイントです。上から下へのパスは次のとおりです:

  1. ユーザー トラフィックはゲートウェイ層からバックグラウンド サービスに転送されます
  2. #バックグラウンド サービスはトラフィックを受け入れ、キャッシュを呼び出してデータを取得します
    # #キャッシュにデータがない場合は、データベースにアクセスします
  3. トラフィックは上から下に層ごとに減少します。ゲートウェイ層は最も集中的なユーザー アクセス リクエストを収集し、次に、バックグラウンドサービス。
バックグラウンド サービスの検証ロジックを通過した後、いくつかの誤ったリクエストはフラッシュされ、残りのリクエストはキャッシュに置かれます。キャッシュにデータがない場合、ファネルの下部にあるデータベースは要求されるため、データベース レベルでのリクエストの数は最小になります (他のコンポーネントと比較して、データベースは同時実行能力が最も悪いリンクであることがよくあります。Alibaba の MySQL が大幅な変更を加えたとしても、単一マシンの同時実行性はコンポーネントと比較できません)

現在の主流のゲートウェイ層には、ソフトウェアに代表される Nginx に加え、Spring Cloud の Gateway や Zuul などのゲートウェイ層コンポーネントが含まれます

Nginx の現在の制限

システム アーキテクチャにおいて、Nginx のプロキシとルーティング転送はゲートウェイ層の非常に重要な機能であり、Nginx 本来の軽量かつ優れた設計により、多くの企業の最初の選択肢となっています。ゲートウェイ レベルから。ほとんどのネットワーク トラフィックに耐えられるフロントエンド ゲートウェイとして使用できるため、電流制限に Nginx を使用することも良い選択です。Nginx では、電流制限に基づいた一般的に使用されるポリシー構成も提供されます。

Nginx は 2 つの電流制限方法を提供します。1 つはレートを制御する方法、もう 1 つは同時接続数を制御する方法です。

レートの制御

limit_req_zone

を使用して単位時間あたりのリクエスト数、つまりレート制限を制限する必要があります

Nginx の現在の制限統計はミリ秒に基づいているため、設定した速度は 2r/s です。この変換は、単一の IP では 500 ミリ秒以内に 1 つのリクエストのみが通過でき、2 番目のリクエストは開始直後のみ通過できることを意味します。 501ミリ秒から。

    コントロールレート最適化バージョン
  • 上記のレートコントロールは非常に正確ですが、プロダクションでは厳しすぎます。実際の状況では、上記のようにミリ秒単位で正確に制御するのではなく、合計時間内の IP ユニットの合計訪問数を制御する必要があります。この設定をオンにするには、burst キーワードを使用できます
  • burst=4各 IP で最大 4 つのバースト リクエストが許可されることを意味します

    同時実行数の制御

    Uselimit_conn_zone limit_conn 2 つの命令で同時実行数を制御できます

    limit_conn perip 10 は、単一の IP が同時に最大 10 個の接続を保持できるように制限することを意味します。 limit_conn perserver 100 は、サーバーが同時に処理できる同時接続の合計数が 100 であることを意味します。

    注: この接続は、リクエスト ヘッダーがバックエンドによって処理された後にのみカウントされます。

    ミドルウェアの電流制限

    分散環境の場合、ミドルウェアは電流制限データを保存する中央ノードのような場所にすぎません。たとえば、制御インターフェイスのアクセス レートを 1 秒あたり 100 リクエストにしたい場合、現在の 1 秒以内に受信したリクエストの数をどこかに保存し、クラスター環境内のすべてのノードがアクセスできるようにする必要があります。では、この一時データを保存するにはどのようなテクノロジーを使用できるのでしょうか?

    それなら Redis に違いないと誰もが思ったはずです。Redis の有効期限機能を使用すると、現在の制限の期間 (1 秒あたり 10 リクエスト、または 10 秒ごとに 10 リクエストなど) を簡単に設定できます。 )。同時に、Redis にはスクリプト プログラミングという特別なスキルもあります。電流制限ロジックをスクリプトに記述し、それを Redis に埋め込むことができます。これにより、電流制限の責任がサービス層から完全に分離されます。強力な同時実行特性と高い利用可能なクラスター アーキテクチャは、大規模クラスターへの現在制限されたアクセスも十分にサポートできます (reids lua)。

    電流制限コンポーネント

    上で紹介した方法に加えて、現在、Sentinel など、同様の機能を提供するオープン ソース コンポーネントがいくつかあります。これは良い選択です。 。 Sentinel は、Alibaba によって作成されたオープン ソース コンポーネントであり、Spring Cloud Alibaba コンポーネント ライブラリに含まれています。Sentinel は、電流制限の豊富な API セットと視覚的な管理コンソールを提供しており、電流制限の管理に簡単に役立ちます。

    アーキテクチャの観点から電流制限設計を検討する

    実際のプロジェクトでは、電流制限方法は 1 つだけ使用されます。電流制限戦略に効果を与えるために、複数の方法が組み合わせて使用​​されることがよくあります。階層の感覚。リソース使用量が最大に達しました。このプロセスでは、電流制限戦略の設計は、上で広く、底部でタイトである前述のファネル モデルを参照することもできます。ファネルのさまざまな部分の電流制限スキームの設計では、次の点に注意する必要があります。現在のコンポーネントの高可用性。

    実際に私が参加したプロジェクトを例に挙げると、商品詳細ページのインターフェースを開発したのですが、モバイルタオバオの転用により、アプリ側のアクセスリクエストはまずアリババのmtopゲートウェイを経由します。ゲートウェイ層では、電流制限は比較的緩くなります。リクエストがゲートウェイを介してバックエンドの製品詳細ページ サービスに到達した後、一連のミドルウェア電流制限コンポーネントを使用して、サービス上でより詳細な電流制限制御が実行されます

    電流制限を実装する具体的な手段

    1) Tomcat は maxThreads を使用して電流制限を実装します。

    2) Nginx の limit_req_zone とバーストは、レート制限を実装するために使用されます。

    3) Nginx の limit_conn_zonelimit_conn の 2 つの命令は、同時接続の総数を制御します。

    4) タイム ウィンドウ アルゴリズムは、Redis の順序付きコレクションを利用して実装できます。

    5) リーキー バケット アルゴリズムは、Redis-Cell を使用して実装できます。

    6) トークン アルゴリズムは、Google の guava パッケージを解決することで実装できます。

    Redis で実装された電流制限ソリューションは分散システムで使用できますが、guava で実装された電流制限ソリューションはスタンドアロン環境にのみ適用できることに注意してください。サーバー側の電流制限が面倒だと感じる場合は、プロジェクトのビジネス ニーズを満たすことができる場合に限り、コードを変更せずにコンテナーの電流制限 (Nginx または Tomcat) を直接使用できます。

    Tomcat の現在の制限

    Tomcat 8.5 バージョンの最大スレッド数は、conf/server.xml 設定にあります。maxThreads は最大スレッド数です。 Tomcat のリクエスト時 同時実行数がこの値 (maxThreads) より大きい場合、リクエストは実行のためにキューに入れられ、電流制限の目的が完了します。 ######知らせ:###

    maxThreads の値は適切に増やすことができます。Tomcat のデフォルトは 150 (Tomcat バージョン 8.5) ですが、この値は大きいほど良いわけではありません。特定のサーバー構成によって異なります。毎回注意する必要があります。スレッドが開始されると、スレッド スタック用に 1MB の JVM メモリ領域が必要になり、スレッドが増えるほど GC の負担が重くなります。

    最後に、オペレーティング システムにはプロセス内のスレッド数に一定の制限があることに注意してください。Windows の各プロセスのスレッド数は 2000 を超えることはできません。 Linux の各プロセスのスレッド数は 1,000 を超えることはできません。

以上が電流制限と一般的な解決策を 10 分で理解します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はJava后端技术全栈で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。