目次
基本的な紹介
NGINX は、limit_req_zone と limit_req という 2 つの命令を通じてレート制限を実装します。命令limit_req_zoneは速度制限パラメータを定義し、命令limit_reqはその場所で定義された速度を有効にします。
QPS (1 秒あたりのクエリ レート) は、特定のクエリ サーバーが指定された期間内に処理するトラフィックの量の尺度です。QPS = req/sec = リクエスト/秒の数、つまり 1 秒あたりの応答リクエストの数であり、これが最大スループット能力です。
モジュール構成の詳細な解釈
limit_req_zone
このディレクティブは共有メモリ領域のレート制限とパラメータを設定しますが、実際にはリクエスト レートを制限しません。contexts
したがって、 のディレクティブを使用して、limit_req
その制限を特定のブロックに適用するlocation
必要がありますserver
。
制限要求ゾーン
req_limit_zone という名前の IP に基づいてリクエストを制限し、10M の共有メモリ領域を開き、1 秒あたり 10 リクエストを処理する方法を定義します。
limit_req_zone $binary_remote_addr zone=req_limit_zone:10m rate=10r/s;
説明: 通常、limit_req_zone ディレクティブは、複数のコンテキストで使用できるように HTTP ブロックで定義され、次の 3 つのパラメーターが必要です。
- key - アプリケーションの制限を定義するリクエストの特性。この例では、Nginx 埋め込み変数 binary_remote_addr (バイナリ クライアント アドレス) を使用します。
- ゾーン - 各 IP アドレスのステータスと制限されたリクエスト URL アクセスの頻度を保存するために使用される共有メモリ領域を定義します。メモリ共有領域に保存された情報は、Nginx ワーカープロセス間で共有できることを意味します。定義は 2 つの部分に分かれています。zone=keyword によってゾーンを識別する名前と、その後に続くゾーン サイズです。16,000個のIPアドレスのステータス情報は約1MB必要となるため、例の領域には160,000個のIPアドレスを格納できます。
- rate - 最大リクエストレートを定義します。この例では、レートは 1 秒あたり 10 リクエストを超えることはできません。Nginx は実際にはミリ秒単位でリクエストを追跡するため、レート制限は 100 ミリ秒ごとに 1 リクエストに相当します。「バースト」は許可されていないため、前のリクエストから 100 ミリ秒以内に到着したリクエストは拒否されることを意味します。
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
location /login/ {
limit_req zone=mylimit;
proxy_pass http://my_upstream;
}
}
制限要求
limit_req ディレクティブは、その制限を特定の場所またはサーバー ブロックに適用します。
limit_req zone=req_limit_zone burst=10 nodelay;
- limit_reqzone=req_limit_zone; 各 IP アドレスは、1 秒あたり 10 件の URL リクエストに制限されており、より正確には、前のリクエストから 100 ミリ秒以内に URL をリクエストすることはできません。
- limit_reqzone=req_limit_zoneburst=10;バーストパラメータは、req_limit_zone で指定されたレートを超えた場合にクライアントが開始できるリクエストの数を定義します (この例では req_limit_zone ゾーン、レートは 1 秒あたり 10 リクエスト、または 100 ミリ秒ごとに 1 リクエストに制限されています) )。前のリクエストから 100 ミリ秒以内に到着したリクエストはキューに入れられ、キュー サイズを 10 に設定します。
つまり、特定の IP アドレスから 11 個のリクエストが送信された場合、Nginx は最初のリクエストをすぐに上流のサーバー ファームに送信し、残りの 10 個のリクエストをキューに入れます。その後、キューに入れられたリクエストを 100 ミリ秒ごとに転送し、受信リクエストによってキュー内のキューに入れられたリクエストの数が 10 を超えた場合にのみ、Nginx はクライアントに 503 を返します。
- limit_reqzone=req_limit_zoneburst=10 nolay; nolay パラメータを使用すると、遅延のないキューイングが実現できます; Nginx は引き続きバーストパラメータに従ってキュー内の位置を割り当てます. リクエストが到着すると、Nginx はリクエストが到着している限り、すぐにそれを転送しますこのリクエストにより、キュー内に位置を割り当てることができます。キュー内のこの位置は「使用済み」としてマークされ、しばらく経つまで (この場合は 100 ミリ秒)、別の要求で使用できるように解放されません。
limit_req zone=name [burst=number] [nodelay | delay=number];
location /login/ {
limit_req zone=mylimit burst=20 nodelay;
proxy_pass http://my_upstream;
}
- 上記の設定では、burst=20 を設定します。これは、ゾーンで指定されたレートを超えてクライアントが実行できるリクエストの数を定義します (前に定義した mylimit ゾーンの場合、リクエスト レートは 1 秒あたり 10 リクエストに制限されています) 100 ミリ秒ごとに 1 リクエストです。)。前のリクエストから 100 ミリ秒以内に到着したリクエストはキューに入れられます。ここではキュー サイズを 20 に設定します。
- 22 個のリクエストが同時に送信された場合、NGINX は関連するルールに従って最初のリクエストをすぐに上流サーバーに転送し、次の 2 から 21 までの合計 20 個のリクエストをキューに入れ、直接送信すると言われています。 503 コードを返します。 22 番目のリクエストでは、次の 2 秒間で、リクエストが 100 ミリ秒ごとにキューから取り出され、処理のために上流のサーバーに送信されます。
原理: リーキーバケットアルゴリズム
Leaky Bucket アルゴリズムは、フロー制御と電流制限に使用される古典的なアルゴリズムです。基本原理は、リクエストを固定容量の「バケット」に入れ、バケット内のリクエストは固定レートで送信されます。バケットがいっぱいになると、新しい受信リクエストは破棄されます。リーキー バケット アルゴリズムにより、リクエストの処理速度を一定に保つことができるため、トラフィックの急増によるサービスの不安定性を効果的に防ぐことができます。
ホスト インターフェイスがデータ パケットをネットワークに送信する場合、リーキー バケット アルゴリズムを使用してインターフェイスの出力データ フロー レートを一定にすることができます。
-
不規則なデータ ストリームを出力するホストは、水を水で満たす蛇口のようなものです。
-
アルゴリズムで定義されたリーキーバケットはバケットに似ています
-
漏れのあるバケツに不規則なデータ フローが入力されることは、漏れのあるバケツに水を注ぐことに似ています。
流量出力のリーキーバケツは、水が漏れるリーキーバケツに似ています。
次に、データ パケット送信プロセスにおけるリーキー バケット アルゴリズムの実装原理を詳しく見てみましょう。
1. キューは、転送されるデータ パケットを受信します。
2. キューがスケジュールされ、転送の機会が得られます。キューはトラフィック シェーピングを使用して設定されているため、キュー内のデータ パケットは最初にリーキー バケットに入ります。
3. データ パケットがリーキー バケットに到達するレートとリーキー バケットの出力レートとの関係に基づいて、データ パケットが転送されるかどうかを決定します。
到着レート ≤ 出力レートの場合、リーキー バケットは効果がありません。
到着レート > 出力レートの場合、リーキー バケットが現時点でのトラフィックに耐えられるかどうかを検討する必要があります。
- 1) データ パケットの到着レート - リーキー バケットの流出レート ≤ 設定されたリーキー バケットのバースト レートの場合、データ パケットは遅延なく送信できます。
- 2) データ パケットの到着レート - リーキー バケットの流出レート > リーキー バケットの設定されたバースト レートの場合、超過したデータ パケットはリーキー バケットに格納されます。リーキー バケットに一時的に格納されたデータ パケットは、リーキー バケットの容量を超えることなく遅延して送信されます。
- 3) データ パケットの到着レート - リーキー バケットの流出レート > リーキー バケットの設定されたバースト レートで、データ パケットの数がリーキー バケットの容量を超えた場合、これらのデータ パケットは破棄されます。