リスティング広告を出していたりすると、出稿時に大量のアクセス(確認クローラ)が来てサイトの負荷が急上昇することがあるよね。
さくら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以下のスタティックファイルだけキャッシュすることができる。
(734)