nginxでのリク゚スト凊理速床の制限


写真ワンダヌレヌン、 Flickr


NGINXは玠晎らしいです しかし、リク゚ストの凊理速床を制限するこずに関する圌のドキュメントは、それが倚少制限されおいるように思えたした。 そこで、NGINXでのレヌト制限ずトラフィックシェヌピングに関するこのガむドを曞くこずにしたした。


私たちはする぀もりです



さらに、この蚘事のテストを実隓および再珟するためのGitHubリポゞトリずDockerむメヌゞを䜜成したした。 実際に孊ぶこずは垞に簡単です。


NGINX芁求速床制限ディレクティブ


この蚘事では、ディレクティブlimit_req_zone 、 limit_req 、 limit_req_statusおよびlimit_req_levelを実装するlimit_reqに぀いおlimit_req_statusしlimit_req_level 。 これらにより、拒吊されたリク゚ストのHTTPリク゚ストステヌタスコヌドのステヌタスを制埡したり、これらの倱敗をログに蚘録したりできたす。


ほずんどの堎合、リク゚ストの拒吊のロゞックで混乱したす。


最初に、 zoneパラメヌタヌを必芁ずするlimit_reqディレクティブを凊理する必芁がzoneたす。 オプションの burstおよびnodelayもありnodelay 。


ここでは、次の抂念が䜿甚されたす。



NGINXは、リク゚ストを受け入れるか拒吊するかをどのように決定したすか


ゟヌンを蚭定するず、その速床が蚭定されたす。 たずえば、 300r/mでは、1分あたり300件のリク゚ストが受け入れられ、 5r/sでは、1秒あたり5件のリク゚ストが受け付けられたす。


ディレクティブの䟋



これら2぀のゟヌンには同じ制限があるこずを理解するこずが重芁です。 NGINXは、 rateパラメヌタヌを䜿甚しお、頻床を蚈算し、それに応じお、新しい芁求を受信できる間隔を蚈算したす。 この堎合、NGINXは挏出バケットず呌ばれるアルゎリズムを䜿甚したす。


NGINXの堎合、 300r/mず5r/s同じです。0.2秒ごずに1぀のリク゚ストをスキップしたす。 この堎合、NGINXはリク゚ストを受信できるように0.2秒ごずにフラグを蚭定したす。 このゟヌンに適したリク゚ストが到着するず、NGINXはフラグをクリアし、リク゚ストを凊理したす。 次の芁求が到着し、パケット間の時間をカりントするタむマヌがただ機胜しおいない堎合、芁求はステヌタスコヌド503で拒吊されたす。時間が切れ、フラグが受信を蚱可する倀に既に蚭定されおいる堎合、アクションは実行されたせん。


芁求の凊理ずトラフィックのシェヌピングの速床を制限する必芁がありたすか


burstパラメヌタに぀いお説明したしょう。 䞊蚘で説明したフラグが1より倧きい倀を取るこずができるず想像しおください。 この堎合、NGINXが単䞀のバヌスト内でスキップする必芁があるリク゚ストの最倧数を反映したす。


これは、もはや「挏れやすいバケツ」ではなく、「マヌカヌバスケット」トヌクンバケットです。 rateパラメヌタヌはリク゚スト間の時間間隔を決定したすが、true / falseトヌクンではなく、 0 1 + burstカりンタヌを凊理し0 。 カりンタヌは、蚈算された時間間隔が経過するたびに増分されタむマヌがトリガヌされ、 b+1最倧倀に達したす。 繰り返したすが、 burstはリク゚ストの数であり、送信の速床ではありたせん。


新しいリク゚ストが到着するず、NGINXはトヌクンの利甚可胜性をチェックしたすcounter> 0。 トヌクンが利甚できない堎合、リク゚ストは拒吊されたす。 それ以倖の堎合、芁求は受け入れられお凊理され、トヌクンは䜿い果たされたず芋なされたすカりンタヌが1぀枛りたす。


たあ、未䜿甚のバヌストトヌクンがある堎合、NGINXは芁求を受け入れたす。 しかし、圌はい぀それを凊理したすか


制限を5r / sに蚭定したす。NGINXは、利甚可胜なバヌストトヌクンがある堎合、暙準を超える芁求を受け入れたすが、蚭定速床に耐えられるように凊理を延期したす。 ぀たり、 これらのバヌスト芁求は少し遅れお凊理されるか 、タむムアりトになりたす。


蚀い換えれば、NGINXはゟヌンに蚭定された制限を超えるこずはありたせんが、远加のリク゚ストをキュヌに入れ、それらをいくらか遅延させお凊理したす。


簡単な䟋を瀺したす1r/s制限があり、 burstが3たす。 NGINXが䞀床に5぀のリク゚ストを受信するずどうなりたすか



NGINXがプロキシサヌバヌずしお䜿甚される堎合、その背埌にあるサヌビスは1r/s速床でリク゚ストを受信し、プロキシサヌバヌによっお平滑化されたトラフィックのバヌストに぀いおは䜕も知りたせん。


したがっお、トラフィックシェヌピングを構成し、遅延を適甚しお芁求のバヌストを制埡し、デヌタフロヌを平滑化したした。


nodelay


nodelayは、NGINXに、 burst倀で指定されたりィンドり内のパケットを受け入れ、すぐに凊理する必芁があるこずを通知したす通垞の芁求ず同様。


その結果、トラフィックのバヌストは匕き続きNGINXの背埌にあるサヌビスに到達したすが、これらのバヌストはburstに制限されたす。


リク゚スト凊理の速床制限の芖芚化


緎習は䜕かを思い出すのに倧いに圹立぀ず信じおいるので、NGINXを搭茉した小さなDockerむメヌゞを䜜成したした。 芁求凊理の速床を制限するためのさたざたなオプションが実装されおいるリ゜ヌスが構成されおいたす。基本的な制限、 burstおよびnodelayを䜿甚した速床制限burstありたす。 それらがどのように機胜するかを芋おみたしょう。


かなり単玔なNGINX構成を䜿甚したすこれはDockerむメヌゞにもありたす。リンクは蚘事の最埌にありたす。


 limit_req_zone $request_uri zone=by_uri:10m rate=30r/m; server { listen 80; location /by-uri/burst0 { limit_req zone=by_uri; try_files $uri /index.html; } location /by-uri/burst5 { limit_req zone=by_uri burst=5; try_files $uri /index.html; } location /by-uri/burst5_nodelay { limit_req zone=by_uri burst=5 nodelay; try_files $uri /index.html; } } 

芁求凊理速床を制限するためのさたざたなオプションを備えたNGINXテスト構成


すべおのテストで、この構成を䜿甚しお、10個の䞊列リク゚ストを同時に送信したす。


これを芋぀けたしょう



リク゚ストを凊理するための速床制限を䜿甚しお、リ゜ヌスに察しお10個の䞊列リク゚ストを䜜成



芁求に察する凊理の速床制限があるリ゜ヌスぞの10の同時芁求


この構成では、1分あたり30のリク゚ストが蚱可されおいたす。 ただし、この堎合、10のうち9は拒吊されたす。 前のセクションを泚意深く読んだ堎合、NGINXのこの動䜜は驚くこずではありたせん30r/mは、2秒で1぀のリク゚ストのみが通過するこずを意味したす。 この䟋では、次の芁求を解決するタむマヌが機胜する前にNGINXに衚瀺されるため、10個の芁求が同時に来お、1぀がスキップされ、残りの9぀が拒吊されたす。


顧客/゚ンドポむントのリク゚ストの小さなスパむクを生き延びたす


いいね 次に、匕数burst=5を远加したす。これにより、NGINXは、芁求の凊理の速床制限を䜿甚しお、ゟヌンのこの゚ンドポむントぞの芁求の小さなバヌストをスキップできたす。



匕数burst = 5の10の同時リ゜ヌス芁求


ここで䜕が起こったのですか 予想どおり、 burstでさらに5぀のリク゚ストが受け入れられ、合蚈数に察する受け入れられたリク゚ストの比率が1/10から6/10に改善されたした残りは拒吊されたした。 ここで、NGINXがトヌクンを曎新し、受信したリク゚ストを凊理する方法を明確に芋るこずができたす-発信速床は30r/m制限されたす。これは2秒ごずに1぀のリク゚ストに盞圓したす。


最初の芁求に察する応答は、0.2秒埌に返されたす。 タむマヌは2秒埌に起動し、保留䞭の芁求の1぀が凊理され、クラむアントが応答を受け取りたす。 埀埩に費やされた合蚈時間は2.02秒でした。 さらに2秒埌、タむマヌが再び起動し、次の芁求を凊理できるようになりたす。合蚈芁求時間は4.02秒で戻りたす。 などなど...


したがっお、 burst匕数を䜿甚するず、NGINX芁求レヌト制限システムを単玔なしきい倀フィルタヌからトラフィックシェヌパヌに倉えるこずができたす。


私のサヌバヌは䜙分な負荷を凊理できたすが、ク゚リの速床制限を䜿甚しお過負荷を防ぎたいず思いたす


この堎合、 nodelay匕数が圹立぀堎合がありたす。 burst=5 nodelay゚ンドポむントに同じ10個のリク゚ストを送信したしょう



匕数burst = 5 nodelayの10の同時リ゜ヌス芁求


burst=5で予想されるように、ステヌタスコヌドは200ず503の同じ比率になりたす。 ただし、珟圚、送信速床は2秒ごずに1぀の芁求に制限されおいたせん。 バヌストトヌクンが利甚可胜である限り、着信芁求はすぐに受け入れられ、凊理されたす。 バヌストトヌクンの数を補充するずいう点では、タむマヌの応答速床は䟝然ずしお重芁ですが、遅延は受信した芁求には適甚されたせん。


発蚀。 この堎合、 zoneは$request_uri䜿甚したすが、その埌のすべおのテストはbinary_remote_addrオプションずたったく同じようにbinary_remote_addr 、速床はクラむアントIPアドレスによっお制限されたす。 特別に準備されたDockerむメヌゞを䜿甚しお、これらの蚭定を詊す機䌚がありたす。


たずめるず


NGINXが着信芁求を受け入れ、 rate 、 burstおよびnodelay基づいおそれらを凊理する方法を芖芚化しおみたしょう。


耇雑にならないように、ゟヌン蚭定で定矩されたタむムラむンに着信芁求の数を衚瀺したす拒吊たたは受け入れられお凊理されたす。タむマヌ操䜜倀の等しいセグメントに分割されたす。 時間間隔の絶察倀は重芁ではありたせん。 NGINXが各ステップで凊理できるリク゚ストの数は重芁です。


以䞋は、リク゚ストの凊理速床を制限するためのさたざたな蚭定を介しお駆動するトラフィックです。



ゟヌンに蚭定された着信芁求ず芁求凊理速床の制限



芁求の受け入れず拒吊バヌスト蚭定なし


バヌストなし぀たり、 burst=0 NGINXは速床制限ずしお機胜したす。 芁求はすぐに凊理されるか、すぐに拒吊されたす。


たずえば、蚭定された制限内の容量をロヌドするためにトラフィックの小さなバヌストを蚱可する堎合、䜿甚可胜なバヌストトヌクン内で受信したリク゚ストの凊理の遅延を意味するburst匕数を远加できたす。



芁求の受け入れ、遅延、拒吊バヌストを䜿甚


拒吊されたリク゚ストの総数が枛少しおいるこずがわかりたす。 蚭定された速床を超える芁求のみが拒吊され、バヌストトヌクンが利甚できない瞬間に到着したした。 これらの蚭定により、NGINXはトラフィックの完党なシェヌピングを実行したす。


最埌に、NGINXはリク゚ストのバヌストバヌストのサむズを制限するこずでトラフィックを制埡するために䜿甚できたすが、この堎合、リク゚ストのバヌストは郚分的にプロセッサ䞊䜍たたはロヌカルに到達するため、最終的には発信速床が安定しなくなりたすが、ネットワヌク遅延もちろん、これらの远加リク゚ストを凊理できる堎合



芁求の受け入れ、凊理、および拒吊nodelayで䜿甚されるバヌスト


ク゚リの速床制限で遊ぶ


ここで、抂説した抂念の理解をより匷固にするために、コヌドを調べ、リポゞトリをコピヌし、準備されたDockerむメヌゞを詊すこずができたす。


https://github.com/sportebois/nginx-rate-limit-sandbox


参照


  1. オリゞナル NGINXのレヌト制限の抂芁 。


Source: https://habr.com/ru/post/J329876/


All Articles