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 スクリプトはリクエスト中に渡された時間に基づいて計算を実行するため、分散ノードで取得された時間が同期されていることを確認することが重要です。時刻が同期されていない場合、電流制限機能が正しく動作しません。 著者について オレンジ ファイナンシャル イノベーション センターの開発エンジニアである Duan Ran 氏は、現在、同社のプラットフォーム構築とメディア機能の集約を担当しています。 |
<<: 20 年経った今でも、Salesforce は SaaS の王者ですが、私たちはどうでしょうか?
月収10万元の起業の夢を実現するミニプログラム起業支援プランMetInfoの企業サイト構築システムは...
データの可用性とセキュリティから大規模な言語モデルとその選択と監視まで、企業による生成 AI の導入...
少し前に、PC ベースの Web サイト用のモバイル サイトを構築しました。わずか 1 週間で、We...
アマゾンは2月2日、2020年12月31日までの第4四半期の決算を発表した。2020年第4四半期のア...
インターネットには、初心者のウェブマスターが分析し、高品質のオリジナルコンテンツを作成するためのさま...
私は沈心玲という名の台湾の少女の物語についての記事を読みました。彼女は12歳の時にすでにウェブサイト...
今は万全の態勢を整える時代です。検索エンジン最適化は、Web ページから、doc ドキュメントの最適...
クラウド コンピューティングが登場すると、企業のプログラマーと運用チームの生活は劇的に変化しました。...
ユーザーはなぜクリックしてウェブサイトに入るのでしょうか?検索エンジンはなぜインターネット環境を絶え...
「Baiduオリジナルコンテンツ」は、ウェブマスターの間で常に話題になっています。Baiduのアルゴ...
Vultr は南米ブラジルに独自のデータセンターを持ち、ブラジルのクラウド サーバー サービスを提供...
ウェブサイトの起源私は会社員で、現在30歳です。2012年以前は、いつもオンラインゲームをするのが好...
この話題は少々極端で恣意的ですが、全く不合理というわけではありません。ジャック・マーがインターネット...
[[235895]] 「入社2日目から業務に慣れ、開発業務に取り組み始めました。」貴州大学省実証ソフ...
1 OpenStackについてこれは、パブリック クラウドとプライベート クラウドの展開と管理を実装...