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)

推薦する

JavaScript+html はフロントエンドページでランダム QR コード検証を実装します

クールなフロントエンドページのランダムQRコード検証を参考までに共有します。具体的な内容は次のとおり...

Vue.jsはコンポーネントを通じてアイコンを処理します

アイコン処理ソリューションこの記録の目的は、element-plus 以外のアイコンをコンポーネント...

MySQL シリーズ 12 バックアップとリカバリ

目次チュートリアルシリーズ1. バックアップ戦略の説明1. バックアップの種類2. バックアップで考...

「さらに表示」ボタンによる複数行テキストの切り捨てに関する考察

最近、たまたまこの小さな要件に遭遇しました。昔、JS を使用してこれを処理したことを覚えていますが、...

CSS3 で実装された価格表

結果: 実装コードhtml <div id="価格表" class=&qu...

Vue の nextTick について話す

データが変更されても、DOM ビューはすぐには更新されません。変更直後にノードまたはその値を取得しよ...

Node.js を使用してパスワード ジェネレータを作成するための完全な手順

目次1. 準備2. コマンドラインの記述2.1 バージョンと説明を追加する2.2 パスワードの長さを...

Nginx プロキシを使用してフロントエンドのクロスドメイン問題を解決する方法

序文Nginx (「エンジン エックス」と発音) は、リバース プロキシ、ロード バランサ、HTTP...

Vue プロジェクトがページング効果を実現

ページング効果は、参考までにvueプロジェクトに実装されています。具体的な内容は次のとおりです。 1...

Vueを使用して天気コンポーネントをロードする方法の詳細な説明

この記事では、Vueを使用して天気コンポーネントをロードする方法を参考までに紹介します。具体的な内容...

Vue で計算プロパティを使用する際の知識ポイントのまとめ

計算されたプロパティ場合によっては、テンプレートにロジックを詰め込みすぎると、テンプレートが重くなり...

Jenkins Docker 静的エージェント ノードのビルド プロセス

静的ノードはマシン上に固定されており、いくつかの固定コマンドを通じて起動されます。動的ノードには複数...

nofollowタグの使用と分析に関する簡単な説明

nofollowをめぐる論争Zac と Guoping の間では、nofollow が PR を無駄...

ハイパーリンクAタグを学ぶ

聞く: CSS を使用してハイパーリンクのスタイルを設定しましたが、ホバーしても機能しません。なぜこ...

MySQLトリガーの詳細な説明と簡単な例

MySQLトリガーの簡単な例文法CREATE TRIGGER <トリガー名> -- トリ...