Nginx の limit_req

Nginxの流量制限する場合に使用される limit_req の使い方について調べてみました。 NGINX Rate Limiting の簡単なメモになります。

limit_req

Nginxのrate limitでは、パケット通信の帯域制限などで使われているleaky bucket algorithmに従ってキューイングします。

基本的な設定

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    ...

    server {

        ...

        location /search/ {
            limit_req zone=one burst=5;
        }

ひとつずつ設定を見ていきます。

まず、limit_req_zone directive で httpリクエストに対する制限を定義できます。 ここではあくまでも定義しているだけなので、実際に実装する場合は location ディレクティブ内などに設定を書く必要があります。 limit_req_zone は key、zone、rateという3つのパラメーターを持ちます。

key

その右にある $binary_remote_addr はクライアントのIPアドレスを表現するNginxの変数です。

zone

アクセス制限のかけたURLに対して頻繁にアクセスしてくるそれぞれのIPアドレスを記録するためのメモリについての設定です。 これはNginxのワーカープロセス間で共有されます。 目安として1メガバイトには約16,000のIPアドレスを記録することが可能です。 Nginxが新しいIPアドレスを記録する必要があるときにメモリが枯渇している場合は、最も古いIPアドレスを削除し、メモリを開放します。 それでもまだスペースが足りず不十分な場合は503を返します。 また、上記の枯渇問題を防ぐためにNginxは新しいIPアドレスを登録するたびに過去60秒間に使用されていない最大2つのエントリを削除します。

rate

最大のリクエストレートを設定します。 上記の例では、1秒あたり1リクエストを超えることができないことを表していますが、 実際にはNginxはミリ秒の粒度でリクエストを追跡するため100msごとに1つのリクエストに対応します。

burst

burst パラメーターをzoneで指定されたrateを超えてクライアントが実行できるリクエストの数を定義できます。 burstを超えたリクエストは全てキューイングされます。

例: 20スロットが空でリクエストが21個飛んできた場合は、1つをアップストリームに流す。 次に残りの20リクエストをキューイングし、100ミリ秒ごとにデキューする。

burst with nodelay

nodelay が設定された場合は空きスロットがない状態は503、 空きスロットがある場合はリクエストは処理され、スロットが使用済みになります。

例: 20スロットが空でリクエストが21個同時に飛んできた場合は、21リクエスト全て処理をし、20個のスロットを確保する。 その後、100ミリ秒ごとにデキューして消化。

まとめ

burstなし、burstあり、burstあり+nodelayの3パターンあります。

本番環境で使う場合は nodelay をつける場合が多そう。

参考