1. 電流制限の役割 API インターフェースは呼び出し側の動作を制御できないため、リクエスト数が瞬間的に急増すると、インターフェースがサーバーのリソースを過剰に占有し、他のリクエストの応答が遅くなったり、タイムアウトになったり、さらに悪いことにサーバーがクラッシュしたりします。
レート制限とは、アプリケーション サービスの要求を制限することを指します。たとえば、特定のインターフェースのリクエスト制限は 1 秒あたり 100 であり、制限を超えるリクエストはすぐに失敗するか、破棄されます。 電流制限は以下を処理できます:
したがって、パブリックインターフェースには電流制限対策を講じることが最善です。 2. 分散電流制限はなぜ必要なのでしょうか? アプリケーションが単一ポイント アプリケーションである場合、アプリケーションが調整されている限り、アプリケーションが依存するさまざまなサービスも保護されます。 しかし、さまざまな理由から、オンライン ビジネスは主に分散型システムになっています。現在、単一ノードの制限では、そのノード自体しか保護できず、アプリケーションが依存するさまざまなサービスを保護することはできません。また、ノード容量の拡大や縮小時にサービス全体のリクエスト制限を正確に制御することができません。 分散電流制限を実装すると、サービス クラスター全体の要求制限を簡単に制御できます。クラスター全体に対するリクエスト数は制限されているため、サービスが依存するさまざまなリソースも電流制限によって保護されます。 3. 電流制限アルゴリズム 電流制限を実装する方法は多数あります。プログラムでは、インターフェースのトラフィックは通常、1 秒あたりに処理されるトランザクション数 (トランザクション/秒) に基づいて測定されます。 この記事では、最も一般的に使用される電流制限アルゴリズムをいくつか紹介します。
1. ウィンドウカウンタアルゴリズムを修正 固定ウィンドウ カウンター アルゴリズムの概念は次のとおりです。
固定ウィンドウ カウンターは最も単純なアルゴリズムですが、制限の 2 倍を超えることが許可される場合があります。次の状況を検討してください: 1 秒以内に最大 5 つのリクエストが通過でき、最初のウィンドウの最後の 0.5 秒以内に 5 つのリクエストが許可され、2 番目のウィンドウの最初の 0.5 秒以内に 5 つのリクエストが許可されます。これは、1 秒以内に 10 件のリクエストが行われたことを意味します。 2. スライディングウィンドウカウンタアルゴリズム スライディング ウィンドウ カウンター アルゴリズムの概念は次のとおりです。
スライディング ウィンドウ カウンターは、ウィンドウを細分化し、時間の経過とともに「スライド」させるアルゴリズムです。このアルゴリズムは、固定ウィンドウ カウンターによって発生する二重バースト要求を回避しますが、時間間隔の精度が高くなるほど、アルゴリズムに必要なスペース容量が大きくなります。 3. リーキーバケットアルゴリズム リーキーバケットアルゴリズムの概念は次のとおりです。
リーキー バケット アルゴリズムは、多くの場合、キューを使用して実装されます。サービス要求はキューに保存され、サービス プロバイダーはキューから要求を取り出して一定の速度で実行します。過剰なリクエストはキューに入れられるか、直接拒否されます。 リーキーバケットアルゴリズムの欠陥も明らかです。短期間に大量のバースト要求が発生した場合、その時点でサーバーに負荷がかかっていなくても、各要求は応答されるまでしばらくキュー内で待機する必要があります。 4. トークンバケットアルゴリズム トークン バケット アルゴリズムの概念は次のとおりです。
トークン バケット アルゴリズムは、すべての要求を時間間隔内に均等に分散し、サーバーが耐えられる範囲内でバースト要求を受け入れることができます。そのため、広く使用されている電流制限アルゴリズムです。 4. コードの実装 このように重要な機能であるため、Java には当然、電流制限を実装するクラス ライブラリが多数存在します。たとえば、Google のオープンソース プロジェクト guava は、単一ポイント トークン バケットの電流制限を実装する RateLimiter クラスを提供します。 分散電流制限によく使用されるフレームワークには、Hystrix、resilience4j、Sentinel などがありますが、これらのフレームワークではすべてサードパーティ ライブラリの導入が必要です。国有企業などの保守的な企業では、外部ライブラリの導入には何段階もの承認が必要となり、さらに面倒なことになります。 分散電流制限は本質的にクラスターの同時実行性の問題です。広く使用されているミドルウェアである Redis は、単一プロセスと単一スレッドという特性を備えており、分散クラスターの同時実行の問題を自然に解決できます。この記事では、Redis を使って単一リクエスト判定と電流制限を実装する機能について簡単に紹介します。 1. スクリプト 上記の比較の結果、最も適切な電流制限アルゴリズムはトークン バケット アルゴリズムです。電流制限アルゴリズムを実装するには、クエリと計算のために Redis を繰り返し呼び出す必要があります。 1 回の電流制限判定には複数のリクエストが必要となり、時間がかかります。そこで、計算処理をRedis側に置いてLuaスクリプトを書いて実行し、Redisへのリクエスト1回で電流制限判定が完了する方法を採用しました。 トークン バケット アルゴリズムでは、バケット サイズと現在のトークン数を Redis に保存し、定期的に新しいトークンを追加する必要があります。もちろん、最も簡単な方法は、時々 Redis をリクエストして、保存されているトークンの数を増やすことです。 しかし実際には、現在の制限リクエスト間の時間とトークン追加の速度を計算することで、最後のリクエストからこのリクエストまでにトークン バケットに追加する必要があるトークンの数を計算できます。したがって、Redis のトークン バケットには、最後のリクエストの時間とトークンの数を保存するだけでよく、バケット サイズとトークンの追加速度は、パラメータを渡すことで動的に変更できます。 スクリプトを初めて実行したとき、トークン バケットはデフォルトでいっぱいになっているため、データの有効期限をトークン バケットがいっぱいになるまでの時間に設定して、時間内にリソースを解放することができます。 完成した Lua スクリプトは次のとおりです。 2.電流制限を実行する ここでは、Redis スクリプトを呼び出すために Spring Data Redis が使用されます。 Redis スクリプト クラスを記述します。 RedisTemplate オブジェクトを通じてスクリプトを実行します。 rateLimit メソッドに渡されるキーは、現在の制限インターフェースの ID、max はトークン バケットの最大サイズ、rate は 1 秒あたりに復元されるトークンの数、返されるブール値は、リクエストが現在の制限を超えたかどうかを示します。 Redis スクリプトの電流制限が正しく機能するかどうかをテストするために、それをテストするためのユニット テストを作成します。 トークン バケット サイズを 10 に設定し、1 秒あたり 10 個のトークンを復元し、10 個のスレッドを開始して短時間で 30 件のリクエストを実行し、現在の制限クエリごとに結果を出力します。ログ出力: 0.1 秒以内に行われた 30 件のリクエストのうち、最初の 10 個のトークンと時間の経過とともに復元された 1 個のトークンを除き、トークンを取得できなかった残りの 19 件のリクエストはすべて false を返したことがわかります。現在の制限スクリプトは、制限を超えたリクエストを正しく識別しました。このとき、ビジネス側は、システムがビジー状態である、またはインターフェース要求が頻繁すぎるなどのプロンプトを直接返すことができます。 3. 開発中に遭遇した問題 1) Lua変数フォーマット Lua の文字列と数値は、tonumber() と tostring() を介して変換する必要があります。 2) Redis入力 pexpire などの Redis コマンドは小数をサポートしていませんが、Lua の Number 型は小数を格納できます。したがって、Number 型を Redis に渡すときは、小数点によるコマンドの失敗を回避するために、math.ceil() などのメソッドを使用して変換するのが最適です。 3) 時間コマンド Redis はスクリプトとパラメータをクラスター内のすべてのノードにコピーするため、不確実性のあるコマンドの後に書き込みコマンドを実行することはできません。したがって、リクエスト時に時間を渡すことしかできず、Redis Time コマンドを使用して時間を取得することはできません。 バージョン 3.2 以降の Redis スクリプトは redis.replicate_commands() をサポートしており、代わりに Time コマンドを使用して現在の時刻を取得できます。 4) 潜在的な危険 この Lua スクリプトはリクエスト中に渡された時間に基づいて計算を実行するため、分散ノードで取得された時間が同期されていることを確認することが重要です。時刻が同期されていない場合、電流制限機能が正しく動作しません。 |
<<: OpenStack のコマンドラインからアベイラビリティーゾーンを作成する方法は?
>>: シニアアーキテクトの技術共有: 分散システムのパーティショニングの詳細な説明
[51CTO.comより引用] 2018年5月18日〜19日、51CTO主催のグローバルソフトウェア...
昨日、あるウェブサイトを見て、心が折れそうになりました。なぜかわかりますか? 包含数が 0 なのに重...
みなさんこんにちは、Snow Leopardです。あっという間に春がやってきて、4月も3分の1が過ぎ...
Henghost(Hengchuang Technology)は、香港クラウドサーバー、香港独立サー...
高可用性は、システムが継続的かつ中断なく機能を実行する能力として定義され、システムの可用性を測定する...
Forrester は 2021 年の技術予測シリーズを発表しましたが、その中にはエッジ コンピュー...
今日、企業の IT は大きな変化を遂げています。 Splunk による SignalFx の買収やソ...
ブラックリストページとは何でしょうか?簡単に言うと、コンテンツ品質は良いが、Baidu に一度も含ま...
最近、パソコンの電源を入れて最初にやることは、データの変更を確認することではなく、ウェブサイトを開い...
8月18日、世界最高峰のデータサイエンスカンファレンス「KDD 2022」の受賞者が発表されました。...
[[377361]]クロスリージョンとは、一般的に知られている「異地域デュアルアクティブ」や「異地域...
インターネット産業の変革は加速しており、伝統産業を転覆させるペースはさらに加速しており、インターネッ...
10月1日、マイクロソフトはサンフランシスコでの記者会見で次世代のWindowsオペレーティングシス...
最近、IT 業界の専門家は、関連する会議に出席した際に、隠れたテーマを発見しました。多くの人がクラウ...
多くのウェブマスターは、毎日百度のアルゴリズムを研究しています。実は、検索エンジンはユーザーに役立つ...