nginxでクライアントの接続調整をする

 リスティング広告を出していたりすると、出稿時に大量のアクセス(確認クローラ)が来てサイトの負荷が急上昇することがあるよね。

 さくらVPSお名前.com VPS(KVM)の2GBプランくらいでWordpress位の重さのページを素のまま表示させると、毎秒20アクセスとかで一杯一杯になる。

 そんな時は、nginxのリクエスト制御を使うと裏側の負荷上昇を穏やかにできる。

map $http_user_agent $ualimited{
    default ”;
    ~*googlebot 1;
    ~*msnbot 2;
    ~*bingbot 2;
    ~*slurp 3;
    …
}
limit_req_zone $ualimited zone=uazone:10m rate=10r/s;
server {
    …
    location / {
        …
        limit_req zone=uazone burst=200;
    }
}

 limit_req_zoneで、$ualmitedをキーにして、uazoneゾーンを毎秒10リクエストに制限する定義を作っている。
 で、ロケーション / に、limit_reqで定義したuazone制限を適用している。
※burstは、待ち行列の設定。 これが設定されていないと、リミットに達した時点で503エラーとなる。 burstが設定されていると、その値までのリクエストを待ち行列に突っ込んで、逐次処理することができる(burstを超えれば503になる) クローラが来た時にエラーを表示させると評価に問題が出るので、エラーではなく処理を遅延させて、正しく応答させる。
 limit_req_zoneの第一引数の値ごとにカウントするので、通常は$binary_remote_addrとかにして、リモートIPごとに制限するわけだけど、クローラは複数IPでガンガン来るので、ユーザエージェントで判別したいので、mapを使っている。
 if文で制限を直接設定できなかったので、UserAgent文字列から数値型にマッピングして、定義されているUAの場合に数値を与えて、それ以外の時は空にしてある。

 Wordpressであれば、/wp-content以下のファイルはスタティックで処理負荷が軽いので

    location / {
        …
        limit_req zone=uazone burst=200;
    }
    location /wp-content {
        …
    }

のように、wp-contentのロケーションを切れば、wp-content以下には要求制限がかからなくなる。

 前回のプロクシキャッシュを有効化して、

proxy_cache_path /dev/shm/c levels=1:2 keys_zone=cachezone:512m;
server{
    location / {
        …
        limit_req zone=uazone burst=200;
    }
    location /wp-content {
        …
        proxy_cache cachezone;
    }
}

のようにすれば、wp-content以下のスタティックファイルだけキャッシュすることができる。

(715)


カテゴリー: サーバ設定   パーマリンク

コメントを残す

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