Nginx de PHP
昨日書いたのがあまりに技術っぽくない(の割に結構見られてて恥ずかしい)ので、一応フォローのため「NginxでPHPを使う」ということに的を絞って書きます。
注意
Nginxインストール
epelを入れてればyumでもインストールできますが、バージョンが若干古いことや、モジュールを自由に取ったり付けたりできるようにするため、ソースからビルドしてしまいます。
普通に使う分には以下のような手順でOKです。
- ここからソースをダウンロードして、適当な場所に置く
- 展開してソースをビルド&インストール
「ソースからビルド?なにそれこわい」とか思うかもしれませんが超簡単です。
足りないライブラリとか入ってないと闇から抜け出せなくなることも多々ありますが・・・。
ただし、昨日言った通り普通にビルドすると「Transfer-Encoding: chunked」に対応してないらしいので、対応させたい場合はモジュールを持ってきて一緒にビルドしてやる必要があります。
こいつがそのモジュールなので、落としてきて適当な場所に展開しておきましょう。
ソースからインストールすると、起動スクリプトがインストールされずプロセス管理が面倒なので、起動スクリプトも作っておきましょう。
ここから持ってきて、環境に合わせて弄ればとりあえずは動くんじゃないかと思います。
あ、あとNginxを実行するユーザーも作っておくといいんじゃないかと思います。
既にApacheが入っているならapacheユーザーで動かすのでもいいと思います。
$ cd /usr/local/src/ $ wget http://nginx.org/download/nginx-1.0.12.tar.gz $ tar xvzf nginx-1.0.12.tar.gz (出力省略) $ cd nginx-1.0.12/ (普通にインストールする場合) $ ./configure --with-http_stub_status_module $ sudo make $ sudo make install (chunkedを有効にする場合) $ ./configure --with-http_stub_status_module --add-module=/usr/local/src/agentzh-chunkin-nginx-module-ddc0dd5 $ sudo make -j2 $ sudo make install
PHP(PHP-FPM)インストール
これもyumでインストールできる*1んですが、v5.1.6とかクソ古いバージョンが入ってたりするので、これもソースからビルドしてインストールしちゃっています。
ビルド方法は結構いろんな所で書いてあるのでビルドしたことのない方でもググればできるんじゃないかと思いますが、一応configureする際の要点だけ書きます。
そもそも「PHP-FPM」ってなんなの?
NginxではApacheでの「mod_php」のようなモジュールが用意されていないため、外部のプロセスに処理を投げて、リクエストを処理して貰う必要があります。
そこで、PHPを処理するプロセスを管理してくれるのが「PHP-FPM(PHP-FastCGI Process Manager)」なのです。偉いですね。
ちなみに、FastCGIというのは「リクエストが来るたびにプロセスを作ったり捨てたりするなんてもったいない!予めプロセス用意しといて再利用すれば最強!」みたいな仕組みです。
PHP-FPM設定
PHP-FPMのデフォルト設定はPHPをインストールしたディレクトリの「etc」ディレクトリの中にあります。
もし「/usr/local/php/」にインストールした場合は「/usr/local/php/etc/」の中に「php-fpm.conf.default」があるはずなので、そいつを「php-fpm.conf」として同じ場所にコピーして色々と変更します。
設定で変えるべきところは
- 「user」「group」「listen.owner」「listen.group」をNginxを実行するユーザー/グループに合わせる
- 「pm」で始まる設定ほぼ全て
- 「pm = static」にするとPHP-FPM起動時に一気に「pm.max_children」の数のプロセスを立ち上げる
- よって同時に立ち上げるプロセスの数をメモリーと相談して増減させればいいんじゃないかと思います
- 「pm = dynamic」にするとApacheのWorkerプロセスのように動的に増減。起動時には「pm.start_servers」の数だけプロセスを立ち上げる
- staticの場合と同じく最大数をメモリーと相談しながら設定すれば多分なんとかなります
- ずっと同じプロセス使ってるとメモリリークを起こしたりするので「pm.max_requests」である程度リクエスト処理したらプロセスを作りなおさせるようにしたほうが良さげです
- 「pm = static」にするとPHP-FPM起動時に一気に「pm.max_children」の数のプロセスを立ち上げる
プロセス1つあたりのメモリー消費量が思いの外少ない*2ため、「負荷が低い時に少しでもメモリーが欲しいよぉ><」ということでなければstaticにしてしまって搭載メモリー量に合わせてプロセスの数を調整するのが(プロセスを立ち上げたり切ったりする処理がない分)速度や負荷的にはよろしいんじゃないかと思います。
あと、これも起動スクリプトが自動的にはインストールされないっぽいですが、ちゃんと用意されているのでビルドしたあとに起動ファイルをコピーすればいいです。
$ cp /usr/local/src/php-5.3.10/sapi/fpm/php-fpm /etc/init.d/php-fpm $ chmod 744 /etc/init.d/php-fpm
Nginx設定
上記のような手順でビルド&インストールすると「/usr/local/nginx/」以下にインストールしたもの一式が入るはず*3です。
設定ファイル一式は「/usr/local/nginx/conf/」以下にあります。
「nginx.conf」がApacheでの「httpd.conf」にあたるもので、Nginxの主な設定はここで全部やっちゃいます。
これもググれば適切な設定がいろいろ出てくると思いますので、要点だけ説明します。
- 「〜〜〜.php」のアクセスを「fastcgi_pass」を使ってPHP-FPMに投げる
- サーバー環境変数入れるために「include /usr/local/nginx/conf/fastcgi_params;」を入れる
- 「Transfer-Encoding: chunked」を有効にするためには設定を追加する必要あり
- 「worker_rlimit_nofile」「worker_connections」の数はファイルディスクリプタの数を増やす必要あり
- 用途にもよりますが基本的には「keepalive_timeout 0;」にしてKeepAliveを切っておいたほうがいい
以上を踏まえた設定例はこんな感じです。
worker_processes 2; worker_rlimit_nofile 10240; events { worker_connections 10240; use epoll; } http { keepalive_timeout 0; server_tokens off; server { listen 80; server_name xxxx.xxxxxx.com chunkin on; error_page 411 = @my_411_error; location @my_411_error { chunkin_resume; } location ~*\.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /path_to_site/htdocs$fastcgi_script_name; include /usr/local/nginx/conf/fastcgi_params; fastcgi_send_timeout 15s; fastcgi_read_timeout 15s; } location ~ .*\.(jpg|JPG|gif|GIF|png|PNG|swf|SWF|css|CSS|js|JS|inc|INC|ico|ICO) { root /path_to_site/htdocs; break; } } }