IT本記事は、下記ブログ記事を翻訳したものです。執筆者の方に許可をとって翻訳させていただきました。翻訳誤りなどありましたら、下記までご連絡いただければ幸いです。Listingは大好きな使い方なので、ぜひご覧いただきたいと思います。(nodelayは、翻訳能力の問題で表現がかなりわかりにくいので、別記事で書こうと思います。Limitingです。Limitingによって、特定の期間に受け付けるHTTPリクエストの量を制御できます。対象のメソッドは、GETリクエストのようにシンプルなもの、また、ログインフォームなどに使われるPOSTリクエストです。Limitingは、ブルートフォースアタックのリクエスト量を制限するなど、セキュリティ対策を目的として利用されるケースがあります。attacksが参考になるでしょう。一般的には、大量のリクエストから後段のアプリケーションサーバを守る目的にも利用されます。Limitingの基本から、拡張的な設定について解説します。Bucketアルゴリズムを採用しています。本アルゴリズムは、バケツに水がそそがれ、バケツにあいた穴から水が漏れだすようなイメージです。注がれる水の量が漏れ出す水の量を超過すると、バケツから水があふれるでしょう。リクエストを処理する場合を想定しましょう。バケツに注がれる水はユーザからのリクエストであり、バケツのサイズは、ユーザリクエストをFIFOアルゴリズムで処理させるために使われるキューです。漏れ出す水はサーバに処理させるためにバッファから出るリクエストであり、あふれる水は、破棄され・処理されることのないリクエストです。Limitingは2つのディレクティブ(limit_req,limit_req_zone)により設定されます。ディレクティブが定義された箇所にて流量制御が有効化されます。(サンプルの場合、/login/ロケーションへのすべてのリクエストが対象です。複数の箇所(Location)で利用できるよう、httpブロックに定義されることが一般的です。設定には、下記3つのパラメータが必要です。制御対象のリクエスト識別子を定義します。例として、NGINXの変数である$binary_remote_addr(ClientのIPアドレスをbinary化したデータを持つ)を使うケースが挙げられます。パラメータの値で流量制御することを意味します。(我々はメモリ使用量を削減するため、クライアントのIPアドレスを示す$remote_addrではなく、$binary_remote_addrを使用しています。それぞれのIPアドレスがどの程度の間隔でリクエストしているか保存するための、共有メモリの領域とサイズを定義します。このメモリ領域は、それぞれのWorkerプロセスにて共有されます。この定義は、共有メモリの名前を定義するzone部と、コロン(:)で区切られたsize部の2パートを持ちます。16,000個のIPアドレスを保持するため場合、1MBの領域を使用します。上記の設定では160,000のIPアドレスを保持できます。容量が枯渇した場合、使用頻度が最も低いキーが削除されます。最大リクエスト量を定義します。例では、流量は10request/secを超過することができません。NGINXはリクエストをmsecの粒度で記録しており、この例の場合、100msecに1度のみリクエストされるよう、制御します。我々はburstリクエストを許容していないためです。section)もし前のリクエストから100msec以内に到着したものは、rejectされます。ディレクティブは流量制御値、および共有メモリのパラメータを定義します。実際にリクエストを制御するものではありません。ブロックを定義する必要があります。対するリクエストを流量制御しています。secに制限、つまり前のリクエストから100msec以内に再リクエストできないようにしています。Unavailable)を返却します。これは、おそらく我々が望んだ形ではありません。アプリケーションにはバースト的な傾向があるためです。我々は、設定値を超過したリクエストをバッファリングして適切なタイミングに処理したいと考えています。パラメータを利用した例です。定義された流量をどの程度超過できるか、定義します。リクエストが前のリクエストから100msec以内に到着した場合にキューにputされ、キューのサイズには20を設定しています。1つのIPアドレスから同時に21のリクエストが到着した場合、NGINXは最初に到着したリクエストを後段のサーバに即座に転送し、残りの20をキューにputします。次に、キューに入れられたリクエストを100msec毎に転送し、もしキューに入れられたリクエストの数が20を超える場合にのみ、クライアントに503を返却します。設定はトラフィックの流れを適正化しますが、あなたのサイトを遅く見えさせるため実用的ではありません。我々の例では、キュー内の20番目のリクエストは転送されるまでに2秒待たされており、この時点で、クライアントへの応答はもはや役に立たないかもしれません。パラメータを加えます。パラメータに従ってスロットをキューに割り当て、また設定された流量制御を課し、またリクエストが"素早く"到着した場合、NGINXはキューに転送可能なスロットがある限り、ただちに転送します。そのスロットは「利用中」とマークされ、適切な時間が経過するまで(この例では、100ミリ秒後)別の要求によって使用されるように解放されません。前述のように、20スロットのキューが空であり、21の要求が所定のIPアドレスから同時に到着したとします。NGINXは21個の要求すべてを直ちに転送し、キュー内の20個のスロットを転送済みとマークし、100ミリ秒ごとに1個のスロットを解放します。(代わりに25個のリクエストがあった場合、NGINXは直ちに21個を転送し、20個のスロットにはマークを付け、4個のリクエストをステータス503で拒否します)ここで、最初の20リクエストが転送された101msec後に、異なる20のリクエストが同時に到着したことを想定します。その場合、1スロットのみが解放されている状態なので、NGINXは1リクエストを転送し、残りの19リクエストに503を返却します。最初の転送から501msec後に新しい20のリクエストが到着した場合、5スロットが解放されているため、NGINXは直ちに5リクエストを転送し、15リクエストを拒否します。secで制御していることと同等といえます。オプションはリクエスト間の転送間隔を制限せずに、流量制御する場合に便利です。多くのデプロイメントにおいて、limit_reqディレクティブではburstとnodelayパラメータの両方を有効化することを推奨しています。Limitingを組み合わせることで、より複雑な流量制御を実現することができます。WhileListingこの例では、どのようにして流量制御と"ホワイトリスト“を実現するか、示します。ディレクティブの両方を使っています。ブロックでは、ホワイトリストに含まれるIPアドレスの場合、$limitに0を、そうでない場合に$limitに1をセットしています。ディレクティブを使って制御用のキーに値を設定します。1の場合、$limit_keyにクライアントのIPアドレス(binary)をセットホワイトリストIPアドレスのために$limit_keyに空文字列をセット、もしくはクライアントIPアドレスをセットしています。subnets)は流量制御されません。secで流量制御されます。ディレクティブはロケーション:/に対して、最大10のバースト値を設定おり、nodelayオプションを有効化しています。一つのロケーションに設定することが可能です。リクエストがマッチする全ての制御が適用され、最も制限の厳しい制御が使用されます。一つ以上のディレクトリによって遅延させられている場合、最も長い遅延が使用されます。同様に、あるディレクティブが拒絶する条件に一致する場合、他のディレクティブが許容していても、リクエストは拒絶されます。前述のホワイトリストの設定を拡張した例が以下です。}}ホワイトリストに列挙されるIPアドレスは最初の流量制御(req_zone)に合致しませんが、2つ目の流量制御(req_zone_wl)に合致します。secに制御されます。secに制御されます。Limitingによって遅延・拒絶されたログを出力します。"nginx.com"ログエントリーには下記のフィールドが含まれます。制御対象リクエストのログ番号を示します。HTTPリクエストヘッダー(Host)の値デフォルトでは、上記の例の[エラー]に示すように、NGINXは拒絶されたリクエストをエラーレベルで記録します。(遅延要求は1つ下のレベルでログに記録されるため、デフォルトでinfoです)。ログレベルを変更するには、limit_req_log_levelディレクティブを使用します。ここでは、拒否された要求を警告レベルで記録するように設定します。Clientデフォルトでは、クライアントが流量制御値を超過した際、NGINXはステータスコード503を返却します。ディレクティブを使用することで、異なるステータスコードをセットすることが可能です。ディレクティブを使用することで制御することが可能です。all;}Conclusion我々は流量制御に関する多くの機能を実現しています。パラメータといった流量制御機能を拡張する機能などです。同様にホワイトリストやブラックリストに含まれるIPアドレスに異なる流量制御値を与える拡張的な機能や、どのようにして拒絶・遅延されたかログに記録する機能を有しています。Plusの流量制御を試してみてください。part2こんにちは。contr...こんばんわ。TOEICを受けてきました。»プロフィールid:iryond駆け出しアクアテラリストです。サッカー大好き、マラソンは親孝行、昼から外で飲むビールは至高です。Dayに参加しました!月別アーカイブはてなブログをはじめよう!iryondさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。