今までこのブログはロリポップのチカッパプラン(旧チカッパレンタルサーバー)で運用してたんですけど、Google Webマスターツールの「サイトのパフォーマンス」という項目で、お前のサイトは下位20%に入る遅さだと言われた訳です。

ちなみにアクセス数は大体600-800PV/日で、多くても1000PV程度です。なんでもないアクセス数で下位20%はいくらなんでも酷すぎますよね。少しずつでも改善されたら良いなぁと思ってましたが、むしろ重くなっていく傾向にあるので仕方無く、さくらVPSに移行する事にしました。なおこの記事は新サーバに大してアップロードしているので、この記事が見えたら移転できている事になります。
さくらVPS上の環境はnginx + spawn-fcgi + WordPressにします。本音を言えばWordPressも捨ててPythonベースのブログエンジンに移行したかったのですが、相当時間とエネルギーがかかりそうなので、今回は見送りました。
この記事は基本的には以下の情報を自分なりに舐めたという感じです。凄く早くなりそうで楽しみですね。
サーバの準備
早速VPS上のサーバを構築していきます。まずは基本的なセットアップから。最近知ったのですが、ssh-copy-idは便利なので使ってない人は使った方が良いと思います。
server$ yum -y update server$ adduser taichino server$ passwd taichino server$ vim /etc/sudoers # wheelにtaichinoを追加 server$ su - taichino server$ sudo vim /etc/ssh/sshd_config # Portを変更、Rootログインを非許可 local$ ssh-copy-id -i ~/.ssh/id_rsa.pub taichino@machine server$ sudo /sbin/service sshd restart server$ sudo yum -y install zsh server$ chsh # zsh
次にmysql, php, nginxをそれぞれインストールします。この辺はまぁ何でも無いところです。
# mysql $ sudo yum install mysql-server $ sudo chkconfig mysqld on $ sudo service mysqld start $ mysql -uroot # installation check # php $ sudo yum install php $ sudo yum install php-cli $ sudo yum install php-mysql $ sudo yum install php-mbstring $ php -i | grep mysql # installation check ... # nginx $ sudo yum install nginx $ sudo chkconfig nginx on $ sudo service nginx start $ curl [サーバのIP] | grep -i nginx <h1>Welcome to <strong>nginx</strong> on EPEL!</h1> ... # spawn-fcgi $ sudo yum install spawn-fcgi $ sudo chkconfig spawn-fcgi on $ sudo service spawn-fcgi start Starting spawn-fcgi: [FAILED]
spawn-fcgiを起動しようとするとエラーになりました。/etc/init.d/spawn-fcgiを見ると、/etc/sysconfig/spawn-fcgiに適切な起動パラメータを書く必要がありそうです。詳細は理解してませんが、とりあえずデフォルトのサンプルを少し弄って下記のようにしました。
SOCKET=/var/run/php-fcgi.sock OPTIONS="-u nginx -g nginx -s $SOCKET -M 0600 -C 16 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/bin/php-cgi"
これで、spawn-fcgiを起動できます。
$ sudo service spawn-fcgi start Starting spawn-fcgi: [ OK ]
spawn-fcgiもnginxもphpも入った事ですし、この辺でphpinfoでも表示して確認してみたいですね。nginx.confを少し修正して、spwan-fcgiとnginxをつなぎます。
user nginx; worker_processes 1; error_log /var/log/nginx/error.log; #error_log /var/log/nginx/error.log notice; #error_log /var/log/nginx/error.log info; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; # spawn-fcgiをたたくサーバ server { listen 80 default; location / { root /var/www/html; index index.html index.php; } location ~ \.php$ { root /var/www/html; include /etc/nginx/fastcgi_params; fastcgi_pass unix:/var/run/php-fcgi.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } }
nginx.confを修正したら設定をリロードします。
$ sudo service nginx reload Reloading nginx: [ OK ]
/var/www/htmlにphpinfo.phpを置いて、ブラウザでアクセスしてみましょう。おなじみのphpinfoが表示されたら成功です。
WordPressの移行
以上でなんとなくnginxでphpスクリプトを動かせる感じになりました。早速WordPressを移行してみます。実際の移設の前にバックアップを取ります。データベースはロリポップだとphpMyAdminが使えるので、そこからエクスポートすればOKです。またテーマやプラグインなども入れ直すのは面倒なので、FTP等でWordPressのディレクトリごとコピーしておきます。
そしてディレクトリごとコピーしたWordPressを下記に置きました。
$ pwd /var/www/html/taichino.com/
またバックアップファイルを利用してデータベースを復元します。ここでwp_optionsのsiteurl, homeを一旦新しいサーバのIPに書き換えます。こうしておかないと、移転先の管理画面にログインしようとしても古い方のサーバにリダイレクトされてしまう為です。
$ mysql -uroot mysql> create database blog_db; mysql> grant all on blog_db.* to blog_user@localhost identified by 'blog_pass'; mysql> update wp_options set option_value='http://49.212.130.174' where option_name='siteurl'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update wp_options set option_value='http://49.212.130.174' where option_name='home'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> exit; $ mysql -uroot blog_db < dump.sql
これで移行できた気でいたのですが、いざ各記事にアクセスするとエラーになります。なんでと思ってみて見ると、WordPressは.htaccessでパーマリンクの制御を行うようになっていて、apache以外のhttpdを使う場合はhttpd側でRewrite Ruleの面倒を見なければなりません。またcssやjs等のstaticファイルはnginx自身でレスポンスを返す必要があります。下記の様に修正してnginx.confを修正してリロードします。
user nginx; worker_processes 1; error_log /var/log/nginx/error.log; #error_log /var/log/nginx/error.log notice; #error_log /var/log/nginx/error.log info; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; server { listen 80 default; root /var/www/html/taichino.com; location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 24h; access_log off; break; } if (!-f $request_filename){ rewrite /. /index.php last; } location ~ \.php { include fastcgi_params; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/var/run/php-fcgi.sock; } } }
Rewrite Ruleは見ての通り単純で、実ファイルが存在しないリクエストは全部index.phpにRewriteします。一瞬奇妙に感じますがWordPressの内部で、元のURIが保存されているREQUEST_URIを元にエントリを取得するような処理になっているので問題ありません。以上で、nginx + spawn-fcgiでWordPressを動作させる事ができました。
nginxのリバースプロキシ
次にnginxのリバースプロキシの設定を行います。httpディレクティブ中にserverディレクティブをもう一つ追加して、ついでにプロキシキャッシュの設定も追加しましょう。proxy_cache_pathあたりの項目が若干複雑ですが、ドキュメントとにらめっこして頑張ります。そうすると下記のような設定ファイルになりました。
user nginx; worker_processes 1; error_log /var/log/nginx/error.log; #error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log off; proxy_cache_path /var/cache/nginx levels=2 keys_zone=blog_cache:10m max_size=50m inactive=720m; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; server { listen 80 default; access_log /var/log/nginx/access.log main; location / { proxy_cache blog_cache; proxy_cache_valid 200 1d; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_pass http://127.0.0.1:10001; } } server { listen 10001; root /var/www/html/taichino.com; rewrite_log on; location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 24h; access_log off; break; } location / { index index.php; } if (!-f $request_filename){ rewrite /. /index.php last; } location ~ \.php { include fastcgi_params; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/var/run/php-fcgi.sock; } } }
以上で何となくnginx + spawn-fcgi + WordPressを動かし始められました。まだ挙動が怪しいところがありますが、長くなってきたので、取りあえずこの辺で切ります。最後にブログのパフォーマンスのBefore, Afterを張っておきます。
before
after
なんと言うか拍子抜けです。スループットが2.3倍くらいにしか伸びていません。アチラコチラで何十倍とか言われているのに何という体たらく。ただベンチマーク中もCPUの負荷が1%以下推移していて余裕あり過ぎなので、どこかの設定に問題がありそうです。その辺の調整はまたの機会にしたいと思います。それでも一応は無事にブログを移転できて良かったです。