ロリポップから、さくらVPSにブログを移行した話

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

お前のサイトは遅すぎる by Google

ちなみにアクセス数は大体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%以下推移していて余裕あり過ぎなので、どこかの設定に問題がありそうです。その辺の調整はまたの機会にしたいと思います。それでも一応は無事にブログを移転できて良かったです。

Leave a Reply

Your email address will not be published. Required fields are marked *