Nginx の http リソース リクエスト制限の詳細な説明 (3 つの方法)

Nginx の http リソース リクエスト制限の詳細な説明 (3 つの方法)

前提条件: nginx には、ngx_http_limit_conn_module モジュールと ngx_http_limit_req_module モジュールが必要です。コマンド 2>&1 nginx -V | tr ' ' '\n'|grep limit を使用して、対応するモジュールがあるかどうかを確認できます。ない場合は、これらの 2 つのモジュールを再コンパイルしてインストールします。

テストバージョン: nginx バージョン 1.15+

リンクの数を制限する

1. limit_conn_zone ディレクティブを使用してキーを定義し、共有メモリ ゾーンのパラメータを設定します (ワーカー プロセスはこのゾーンを使用してキー値のカウンターを共有します)。最初の引数は、キーとして評価される式を指定します。 2 番目のパラメータ zone は、ゾーンの名前とサイズを指定します。

limit_conn_zone $binary_remote_addr ゾーン=addr:10m;

2. 制限を適用するには、location {}、server {}、または http {} コンテキストで limit_conn ディレクティブを使用します。最初の引数は上記で設定した共有メモリ ゾーン名で、2 番目の引数は各キーに許可される接続数です。

場所 /download/ {
 limit_conn アドレス 1;
}

$binary_remote_addr 変数をパラメータとして使用する場合、制限は IP アドレスに基づいて行われます。また、$server_name 変数を使用して、特定のサーバーへの接続数を制限することもできます。

http {
 limit_conn_zone $server_name ゾーン=servers:10m;

 サーバー{
 limit_conn サーバー 1000;
 }
}

リクエストレートの制限

レート制限は、DDoS 攻撃や CC 攻撃を防いだり、同時に多数のリクエストによってアップストリーム サーバーが過負荷になるのを防ぐために使用できます。この方法は、リーキー バケット アルゴリズムに基づいており、リクエストはさまざまなレートでバケットに到着し、固定レートでバケットから出ていきます。レート制限を使用する前に、「リーキー バケット」のグローバル パラメータを設定する必要があります。

  • キー - クライアントを区別するために使用されるパラメータ。通常は変数です。
  • 共有メモリゾーン - これらのキーの状態を保持するゾーンの名前とサイズ(つまり、「リーキーバケット」)
  • レート - 1 秒あたりのリクエスト数 (r/s) または 1 分あたりのリクエスト数 (r/m) (「リーキー バケット ドレイン」) で指定されたリクエスト レート制限。 1 分あたりのリクエスト数は、1 秒あたり 1 リクエスト未満のレートを指定するために使用されます。

これらのパラメータは、limit_req_zone ディレクティブを使用して設定されます。このディレクティブは http{} レベルで定義されます。このアプローチにより、異なるゾーンとリクエスト オーバーフロー パラメータを異なるコンテキストに適用できます。

http {
 #...

 limit_req_zone $binary_remote_addr ゾーン=one:10m レート=1r/s;
}

この構成では、サイズが 10m バイトの one という名前の共有メモリ ゾーンが作成されます。この領域には、$binary_remote_addr 変数を使用して設定されたクライアント IP アドレスの状態が保持されます。 $remote_addr にはクライアントの IP アドレスも含まれており、$binary_remote_addr には IP アドレスの短いバイナリ表現が保持されることに注意してください。

共有メモリ領域の最適なサイズは、次のデータを使用して計算できます: $binary_remote_addr IPv4 アドレスの値のサイズは 4 バイトで、64 ビット プラットフォーム上のストレージ状態は 128 バイトを占有します。したがって、約 16,000 個の IP アドレスの状態情報がこの領域の 1 MB を占めます。

NGINX が新しいエントリを追加する必要があるときにストレージ スペースが不足すると、最も古いエントリが削除されます。解放されたスペースがまだ新しいレコードを収容するのに不十分な場合、NGINX は 503 Service Unavailable ステータス コードを返します。これは、limit_req_status ディレクティブを使用して再定義できます。

このゾーンが設定されると、NGINX 構成の任意の場所、特に server {} 、 location {} 、および http {} コンテキストで limit_req ディレクティブを使用してリクエスト レートを制限できます。

http {
 #...

 limit_req_zone $binary_remote_addr ゾーン=one:10m レート=1r/s;

 サーバー{
 #...

 場所 /検索/ {
  limit_req ゾーン = 1;
 }
 }
}

上記の設定を使用すると、nginx は /search/ ルートで 1 秒あたり 1 件以下のリクエストを処理し、合計レートが設定されたレートを超えないようにこれらのリクエストを遅延させます。 NGINX は、「バケット」(共有バケット 1)がいっぱいになるまで、このようなリクエストの処理を遅延します。バケット全体に到達するリクエストの場合、NGINX は 503 Service Unavailable エラーで応答します (limit_req_status がカスタム ステータス コードを設定していない場合)。

帯域幅を制限する

接続ごとの帯域幅を制限するには、limit_rate ディレクティブを使用します。

場所 /download/ {
 制限レート 50k;
}

この設定により、クライアントは単一の接続で最大 50k/秒の速度でコンテンツをダウンロードできるようになります。ただし、クライアントは複数の接続を開いてこの制限を回避することができます。したがって、ダウンロード速度が指定された値を超えないようにすることが目的の場合は、接続数も制限する必要があります。たとえば、IP アドレスごとに 1 つの接続 (上記で指定した共有メモリ ゾーンを使用している場合) は次のようになります。

場所 /download/ {
 limit_conn アドレス 1;
 制限レート 50k;
}

クライアントが一定量のデータをダウンロードした後にのみ制限を課すには、limit_rate_after ディレクティブを使用します。クライアントが一定量のデータ (ファイル ヘッダー、映画のインデックスなど) をすばやくダウンロードできるようにし、残りのデータのダウンロード速度を制限する (ユーザーが映画をダウンロードするのではなく視聴できるようにする) のが合理的である可能性があります。

制限レート500k以降;
制限レート 20k;

次の例は、接続数と帯域幅を制限するための組み合わせ構成を示しています。許可される最大接続数は、クライアント アドレスごとに 5 接続に設定されています。これは、最近のブラウザーでは通常、一度に最大 3 つの接続が開かれるため、最も一般的なケースに適しています。また、ダウンロードが提供される場所への接続は 1 つだけ許可されます。

http {
 limit_conn_zone $binary_remote_address ゾーン=addr:10m

 サーバー{
 ルート /www/data;
 limit_conn アドレス 5;

 位置 / {
 }

 場所 /download/ {
  limit_conn アドレス 1;
  1分後の制限レート;
  制限レート 50k;
 }
 }
}

内容は、ドキュメントの nginx リクエスト制限部分から翻訳されたもので、意味が若干調整されています。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • nginx のリクエスト制限(接続制限とリクエスト制限)の詳細な説明
  • Nginx のリクエスト制限とアクセス制御の実装に関する簡単な説明
  • nginx プロキシ傍受リクエストによるグローバルアクセス制限
  • Nginxは、同じ期間内の特定のIPへの訪問とリクエストの数を制限します。サンプルコード
  • Nginx サーバーで接続とリクエストの数を制限するモジュールを構成する方法に関するチュートリアル
  • Nginx リクエスト制限の設定方法

<<:  node.jsミドルウェアの種類についての簡単な説明

>>:  MySQL 5.7.21 解凍版のインストールと設定方法のグラフィックチュートリアル (win10)

推薦する

Docker は固定コンテナ IP アドレスを実現するためにカスタム ネットワークを作成します。

デフォルトのブリッジ ネットワークのため、コンテナーを再起動すると IP アドレスが変更されます。シ...

MySQL のデータ削除とデータ テーブル メソッドの例

MySQL でデータやテーブルを削除するのは非常に簡単ですが、削除するとすべてのデータが消えてしまう...

Tencent Cloud Server Tomcat ポートにアクセスできない場合の解決策

最近、Tencent Cloudを使用してサーバーを設定しました。使用中に、tomcatポートにアク...

MySql SQL最適化のヒントの共有

ある日、内部結合を含む SQL ステートメントの実行速度はそれほど遅くはない (0.1 ~ 0.2)...

vue3 watch と watchEffect の使い方と違い

1.リスナーを見る時計のご紹介 'vue' から { ref, reactive, ...

MySQLのファジークエリの要約

1. 一般的な使用法: (1)%で使用する% は 1 つ以上の文字のワイルドカードを表します。たとえ...

Next.js 入門チュートリアル

目次導入Next.jsプロジェクトを作成するNext.js プロジェクトを手動で作成するcreact...

jQueryフレームワークは、要素の表示と非表示の3つのアニメーションメソッドを実装しています。

目次1. デフォルトで表示と非表示を切り替える2. スライドして表示と非表示を切り替える3. フェー...

CSS+JS で水滴の波紋アニメーション ボタン効果を実装するサンプル コード

コードは次のようになります。 <!DOCTYPE html> <html lang...

MySQL ツリー構造データベース テーブル設計

目次序文1. 基本データ2. 継承駆動設計3. 左右の値のエンコーディングに基づく設計4. ツリー構...

ウェブサイトのカラースキーム ウェブサイトに適した色の選択

色はウェブサイト訪問者に影響を与えますか?数年前までは、ウェブサイトはまだ贅沢品でしたが、今ではほと...

Vue Element Sortablejs を使用してテーブル列をドラッグする詳細な説明

1. css: ドラッグテーブル.css @charset "UTF-8"; ....

JavaScript でよく使われる 3 つの Web エフェクトの詳細な説明

目次1要素オフセットシリーズ1.1 オフセットの概要1.2 オフセットとスタイルの違い視覚領域クライ...

MySQL で 2 つのデータベース テーブル構造を比較する方法

開発およびデバッグのプロセスでは、新しいコードと古いコードの違いを比較する必要があります。比較には、...