WordPressをCentOS+Apache+mod_fastcgi+PHP-FPMを使って動かしてみた

このブログはさくらVPSで動かしているのですが、さくらVPSの一番弱いところはメモリの大きさが 512MBというところなんですよね。PHPみたいなLLは結構メモリは富豪的に使うので mod_php使ってhttpdのメモリを膨れさせてると、同時接続数そんなに上げられないわけです。

アプリケーションサーバをWEBサーバと切り離すのであれば、定番としては WEBサーバとしてApache+mod_proxyやlighttpdやnginxを前段に置いて、 mod_phpで起動したApacheにプロキシして上げるというのが一つのやり方です。 ただ、1台のホストでやってるのでApacheを2種類上げるとかなんか気持ち悪いし、 Apache以外はあんまりよく分からない。

こんな時には、FastCGIを使ってhttpdから切り離すのが常套手段なんですが、 FastCGIを普通に使うとApacheの再起動とFastCGIプロセスの再起動が連動したりするのが 何となくすっきりしないですね。

Perlだと最近はこんな感じで plackで起動させたデーモンにmod_proxyで渡してしまうという手段があって すごい分かりやすくていい感じだなーと思っていて、PHPでこういうやり方が無いのかというのを 調べていたらありました。

PHP-FPMという仕組みがあって、あまりよく確認してないので 推測で書くと、PHPのインタプリタ的なものを適当なポートでデーモン起動させておくことができて、 WEBサーバからそのポートに向けてPHPのスクリプトをプロキシさせることで実現してるっぽいです。 (間違ってたらすいません><)

ただ、Google先生に色々聞いてみても、nginxとの組み合わせばっかりでてきて、Apacheを WEBサーバとして使った場合どうやるのかなーと思ってたら、まさにバッチリなエントリを発見したので ほぼこのまんま導入してみたら、うまくいってしまいました。

というわけで、以下CentOS5でどうやったかの説明になります。

サードパーティのyumレポジトリ追加

CentOS5の標準のyumレポジトリだと、phpのバージョンが古かったりするので、 以下のレポジトリを追加しています。(rpmforgeはphp入れる時の依存でlibeditのために必要でした)

レポジトリの追加はこんな感じです。

cd /usr/local/src
wget http://rpms.famillecollet.com/enterprise/remi-release-5.rpm
wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
rpm -ivh remi-release-5.rpm rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm

これだけだと、remiとrpmforgeもデフォルトで使われてしまって困るパターンがあるので 通常時は使われないようにconfを編集しておきます。

vim /etc/yum.repos.d/remi.repo
vim /etc/yum.repos.d/rpmforge.repo

# ファイルの中のenabled = 1を0に

# enabled = 1
enabled = 0

Apacheのインストール

ApacheはとりあえずCentOS標準レポジトリのものを使ってます。 あとでmod_fastcgiのmakeをするために必要になるのでhttpd-develも入れます。 develの依存関係で他にも色々入ると思います。

yum install httpd httpd-devel

mod_fastcgiのインストール

mod_fastcgiはrpmが見つからなかったのでmakeしています。32bitと64bitでmakeのオプションが違うらしいですが さくらVPSは64bitなのでこんな感じ。

cd /usr/local/src
wget http://www.fastcgi.com/dist/mod_fastcgi-2.4.6.tar.gz
tar xvzf mod_fastcgi-2.4.6.tar.gz
cd mod_fastcgi-2.4.6
cp Makefile.AP2 Makefile
make top_dir=/usr/lib64/httpd
make install top_dir=/usr/lib64/httpd

PHP関係のインストール

僕の場合、MySQLを公式のrpmから入れてしまっているので、php-mysqlだけyumでは入れられなかったので yumdownloaderしてrpmコマンドで入れてる以外は、remiからざくっと入れます。 もしMySQLもyumで入れてしまうなら、php-mysqlもyum installでいいと思います。

yum --disablerepo=* --enablerepo=remi,rpmforge install php php-mbstring php-pdo php-fpm

# php-mysqlだけ別で
yum install yum-utils # yumdownloaderはこれに入ってます
cd /usr/local/src
yumdownloader --disablerepo=* --enablerepo=remi,rpmforge php-mysql
rpm -ivh --no-deps php-mysql-5.3.4-1.el5.remi.x86_64.rpm

各種configの準備

これで必要なバイナリは揃ったので、あとはconfigの整備をしていきます。

/etc/httpd/conf/httpd.conf

各自のサイトに合わせて適当にやって頂ければと思います。 Apache2系のconfはconf.d/*.confに分割して書くのがメジャーらしいですが 僕は結構適当httpd.confに書いちゃってますw

標準のApacheはpreforkでビルドされているので、WEBサーバの数の調整は <IfModule prefork.c>配下で調整しますが、アプリケーションの無いhttpdプロセスはかなり小さいので あんまりシビアになる必要は無いと思います。

/etc/httpd/conf.d/php.conf

これはmod_php用のconfigで、php-fpmで動かすには多分邪魔なのでコメントアウトするか どっかに移動するか消してしまいます。

/etc/httpd/conf.d/fastcgi.conf

さて、これが今回のキモになります。ファイルは無いので自分で新規作成。

LoadModule fastcgi_module modules/mod_fastcgi.so
<IfModule mod_fastcgi.c>
ScriptAlias /fcgi-bin/ "/etc/httpd/fcgi-bin/"
FastCGIExternalServer /etc/httpd/fcgi-bin/php-cgi -host 127.0.0.1:9000 -pass-header Authorization
AddHandler php-fastcgi .php
Action php-fastcgi /fcgi-bin/php-cgi
</IfModule>

中心はFastCGIExternalServerですね。ここに指定したホストにプロキシしてくれます。 その他はあんまりよく理解してないですが、とりあえずコピペで動いちゃったので無視。

で、/etc/httpd/fcgi-binとか無いので、自分で作ります。

mkdir /etc/httpd/fcgi-bin
cp /usr/bin/php-cgi /etc/httpd/fcgi-bin/
chown -R apache: /etc/httpd/fcgi-bin
chmod -R 755 /etc/httpd/fcgi-bin

/etc/php-fpm.d/www.conf

こちらがPHP-FPMを制御するconfです。デフォルトだとプロセス数が負荷に応じて 増減するApacheのpreforkと似たような設定になってますが、僕の目的としては PHPのプロセスの数を固定してメモリの使用量を一定にしておきたいのと 適当に再起動してもらってリークしていても増えないようにしたいのでこんな感じにしました。 これがやりたかったんだッ!人気ブログでもないので3つもあれば十分。

pm = static
pm.max_children = 3

pm.max_requests = 500

では起動!

WordPressは適当に配置してあるとします。(よく分からない人はとりあえず/var/www/htmlとかに展開しとけばよし) あとはPHP-FPMを起動して、Apacheを起動すればもう動くよ!

service php-fpm start
service httpd start

まとめ

PHPをApacheとは別のプロセスで立ち上げて、メモリの使用量を一定にすることができました。 以前はmod_phpで起動していて、preforkの設定を以下の様な感じにするという しょぼいやり方でメモリの使用量を抑えてました。

StartServers       5
MinSpareServers    5
MaxSpareServers   5
ServerLimit       5
MaxClients        5

まぁ悪くは無いんですが、httpdはphp以外にも画像とかcssとかも返してるわけで、 あんまり数が少ないのはよろしくはありませんね。

今回PHP-FPMを使ってプロセス数を固定にすることができたので安心して見ていることができます。 さくらVPSを使う場合にはくれぐれもメモリの使用量とswap発生にはご注意を。