nginx + Apacheで20万PV/日を捌く

GMOクラウドVPSの2GBプランで運営しているWordPressサイトがあるのですが、5万PV/日を超えてだんだん重くなってきたので4GBプランに移行しました。 
■これまでの経緯
・Apache:2GBプランだと2万PV/日くらいで厳しくなる(メモリ不足)
・nginx:5万PV/日を超えたあたりで重くなる(ロードアベレージが高すぎる)

chibiegg日誌を参考に、バックエンドの処理をApache、フロントエンドの処理をnginxにさせて負荷軽減を目指します。

Apacheの設定

不要っぽいモジュールは読み込まないようにします。8080ポートで動くように変更します。

/etc/httpd/conf/httpd.confの一部
StartServers       8
MinSpareServers    5
MaxSpareServers   15
ServerLimit      40
MaxClients       40
MaxRequestsPerChild  1000

Listen 8080

#LoadModule auth_basic_module modules/mod_auth_basic.so
#LoadModule auth_digest_module modules/mod_auth_digest.so
#LoadModule authn_file_module modules/mod_authn_file.so
#LoadModule authn_alias_module modules/mod_authn_alias.so
#LoadModule authn_anon_module modules/mod_authn_anon.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so
#LoadModule authn_default_module modules/mod_authn_default.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
#LoadModule authz_owner_module modules/mod_authz_owner.so
#LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so
#LoadModule authz_default_module modules/mod_authz_default.so
#LoadModule ldap_module modules/mod_ldap.so
#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule include_module modules/mod_include.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
LoadModule env_module modules/mod_env.so
LoadModule ext_filter_module modules/mod_ext_filter.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
LoadModule usertrack_module modules/mod_usertrack.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
#LoadModule dav_module modules/mod_dav.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule info_module modules/mod_info.so
#LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so
#LoadModule actions_module modules/mod_actions.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
LoadModule substitute_module modules/mod_substitute.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule cache_module modules/mod_cache.so
LoadModule suexec_module modules/mod_suexec.so
LoadModule disk_cache_module modules/mod_disk_cache.so
LoadModule cgi_module modules/mod_cgi.so
LoadModule version_module modules/mod_version.so

NameVirtualHost *:8080


        ServerName example.com
        DocumentRoot /home/example.com/html/
        CustomLog       /home/example.com/logs/access8080.log combined
        ErrorLog        /home/example.com/logs/error8080.log



nginxの設定

ポート80で待ち受けてキャッシュ。キャッシュになければ8080に飛ばします。(キャッシュのサイズはどれくらいがいいか分からなかったので適当)
また、wp-adminへの不正アクセスがあるのでIP制限をします。
(記事をスクレイピングされることもあるので、スクレイピングサイトからのアクセスも弾く) /etc/nginx/conf.d/default.conf
proxy_cache_path /var/cache/nginx/static_file_cache levels=1:2 keys_zone=cache_static_file:128m inactive=7d max_size=10g;
proxy_temp_path /var/cache/nginx/temp;

upstream backend{
    server 127.0.0.1:8080;
}

server {
    listen       80;
    server_name  localhost;

    location ~ wp-login\.php$|xmlrpc\.php$|wp-admin/((?!admin-ajax\.php).)*$ {
        allow 許可するIPアドレス;
        allow このサーバーのIPアドレス;
        allow 127.0.0.1;
        deny all;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://backend;
    }

    location / {
        proxy_redirect off;

        set $do_not_cache 0;
        if ($request_method != GET) {
            set $do_not_cache 1;
        }
        if ($uri !~* ".(jpg|png|gif|jpeg|css|js|swf|pdf)$") {
            set $do_not_cache 1;
        }
        proxy_no_cache $do_not_cache;
        proxy_cache_bypass $do_not_cache;
        proxy_cache cache_static_file;
        proxy_cache_key $scheme$host$uri$is_args$args;
        proxy_cache_valid 200 2h;
        proxy_cache_valid any 1m;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://backend;

    }
    deny スクレイピングサイトのIPアドレス;
    allow all;
}

MySQLの設定

上記で運用してみるとMySQLのCPU使用率が高かったので、クエリキャッシュを増やしてみました。
/etc/my.confの一部
query_cache_size=256M
query_cache_limit=16M

mod_rpaf

このままだと、Apacheのアクセスログは常に「127.0.0.1」となってしまいます。
Qiitaさんのブログを参考に、mod_rpafをインストールしました。

上記設定で、ピーク時(Google Analyticsで見たアクティブユーザー400人)でもロードアベレージは2くらいになりました。
このままで20万PV/日くらいまでならこなせると思います。
・php.iniでメモリを減らす
・MySQLをMyISAMからInnoDBに変更
・Apache, nginxのプロセス数調整
などをすればもう少しいけるかも?

  • Spread The Love
  • Digg This Post
  • Tweet This Post
  • Stumble This Post
  • Submit This Post To Delicious
  • Submit This Post To Reddit
  • Submit This Post To Mixx

1 Responses to “nginx + Apacheで20万PV/日を捌く”

  1. Unknown says:
    このコメントはブログの管理者によって削除されました。

Leave a Reply