nginxのlimit_reqの動きで悩んだ

limit_req の制限のかかりかたがなかなか掴めなかったのでメモ。

まずは

limit_req_zone $binary_remote_addr zone=limit_zone:10m rate=1r/s;
limit_req limit_zone;

とすると、leaky bucketというアルゴリズムに基いてIPアドレスごとに1r/sの制限がかかる。超えたぶんは503。

limit_req limit_zone burst = 5;

burst オプションをつけると burst ぶんのリクエスト数まで受け付けるようになって(かつrateに従ってレスポンスを返す)、超えたぶんは503。

limit_req limit_zone burst = 5 nodelay;

になると、burstぶんのリクエストまでは即時レスポンスを返す。それ以降はrateに従う。超えたぶんは503。

何が掴めなかったかというと、burstをつけた場合、burstを超えたと判断されるタイミングは?とか、超えたと判断されたら次はいつburstできるの?とか、そのあたり。nodelayをつけたり外したりしてパニックになってたw

基本的にどのオプションでもleaky bucketのアルゴリズムで処理されていくというのは同じで、nodelayをつけるとレスポンスを即時返すというだけなんだけど、よくわからないうちはnodelayなしで検証するとわかりやすいと思う。

leaky bucketのバケツはqueue構造になっていて、burstはqueueの深さ。rateがworkerの仕事量。nodelayは見かけ上queueと関係なく即時処理されているように見せかけるだけ(つまりqueueには残っている)という感じになっているようなので、burstを超えたかどうか判定されるのはqueueが溢れた時。次にburstできるのはqueueが空になった時だった。

rateを小さく、burstを想定するリクエストより少し大きめにしておいてnodelayを有効にするとDoS対策としても使えそうかな?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です