なうびるどいんぐ

脳みそ常時-3dB

Apacheをpreforkからeventに切り替える

      2018/04/07    HimaJyun

今回はこのブログが乗ってるWeb鯖(Apache)のmpmをpreforkからeventに切り替えました

eventだとPHPが動かないとか言われますが、そこをFastCGIで動かすようにもしてみます。

スポンサーリンク

いざ、event!!

ちなみにですが、Ubuntu ServerにLAMPでインストールしたApacheです。

CentOSだともう少し面倒かもしれない。

まずはCGIを実行出来る様に

さて、PHPをCGIで動かすのですよ、当然ながらCGIが実行できる必要があります。

「/etc/apache2/sites-available/*.conf」に「Options ExecCGI」を設定して下さい。

以下の設定例を参考にして下さい。

<VirtualHost *:80>
	ServerName yourdomain.example.com

	ServerAdmin admin@example.com
	DocumentRoot /var/www/html
	<Directory /var/www/html>
		#このOptionsにExecCGIを追加
		Options ExecCGI
		AllowOverride All
	</Directory>

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

PHP-FPM+FastCGIを設定する。

まずは必要なモノをインストールします。

sudo apt-get install libapache2-mod-fastcgi php5-fpm apache2-mpm-event

次に、エディタで「/etc/apache2/mods-available/fastcgi.conf」を開いて以下の内容を追記して下さい。

AddHandler php5-fcgi .php
Action php5-fcgi /php5-fcgi
Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization

<Directory /usr/lib/cgi-bin>
 Require all granted
</Directory>

多分、以下の様な感じになると思います。

<IfModule mod_fastcgi.c>
	AddHandler fastcgi-script .fcgi
	#FastCgiWrapper /usr/lib/apache2/suexec
	FastCgiIpcDir /var/lib/apache2/fastcgi

	AddHandler php5-fcgi .php
	Action php5-fcgi /php5-fcgi
	Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
	FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization

	<Directory /usr/lib/cgi-bin>
		Require all granted
	</Directory>
</IfModule>

PHP-FPMの設定を調整

今までの設定だと、「/etc/php5/apache2/php.ini」が参照されていたと思います。
php-fpmに切り替えると、「/etc/php5/fpm/php.ini」が参照される様になるので設定を更新しましょう。

内容は同じ(だと思うので)以下のコマンドでコピーしてしまいましょう。

sudo cp /etc/php5/apache2/php.ini /etc/php5/fpm/php.ini

もし心配であればdiffとか使って差分を調べれば良いと思います。

次に、fpmの設定を調整します。
エディタで「/etc/php5/fpm/pool.d/www.conf」を開いて下さい。

ごちゃごちゃと詰まっていると思いますけど、以下の点を変更して下さい。
その他の設定項目は自分の理想に合わせて設定して下さい。

[www]
; fpmの実行ユーザ、Apacheの設定と合わせる方が無難だと思います。
user = www-data
group = www-data

; Unixソケットで動かします、TCP/IPで動かすより軽いらしい
listen = /var/run/php5-fpm.sock

; ソケットにWeb鯖がアクセス出来る様に
; つまり、Apacheの実行ユーザと同じ
listen.owner = www-data
listen.group = www-data

; FPMの動かし方
; dynamic = preforkと同じ感じ、負荷に応じて子プロセスを起こしたり寝かしたり。余計な子プロセスが起きないので省メモリ
; static = 常に一定数の子プロセスで動かす、メモリは食うけどこっちの方が速い
pm = static

; 子プロセスの起動数、「pm」の設定が
; dynamic = 起こす子プロセスの最大数。
; static = 起こす子プロセスの数
pm.max_children = 10

; 起動時に起こす子プロセス数
; staticの場合は設定不要
pm.start_servers = 2

; 待機中の子プロセス数の最小
; staticの場合は設定不要
pm.min_spare_servers = 1

; 待機中の子プロセス数の最大
; staticの場合は設定不要
pm.max_spare_servers = 3

; ここで設定した数のリクエストを捌くとプロセスが再起動する、PHPのメモリリーク防止
pm.max_requests = 500

mpm_eventの設定を調整

さて、せっかくのeventでもスレッドの数が不適切だと無意味です。
スレッド数を調整しましょう。

エディタで「/etc/apache2/mods-available/mpm_event.conf」を開いて下さい。
以下の項目をお好きな様に調整してね。

<IfModule mpm_event_module>
 # サーバ起動時に起こす子プロセス数
 StartServers 2
 # 待機スレッドが足りない時はこの数までスレッドを増やす
 MinSpareThreads 25
 # 待機スレッドが多い時はこの数までスレッドを減らす
 MaxSpareThreads 75
 # 子プロセス当たりのスレッド数
 ThreadsPerChild 25
 # 同時に捌けるリクエスト数
 MaxRequestWorkers 150
 # この数のリクエストを捌くと子プロセスが再起動、PHPのメモリリーク防止
 MaxConnectionsPerChild 1000
</IfModule>

設定を適用する

以下のコマンドを実行して下さい。

sudo a2enmod actions fastcgi
sudo a2dismod mpm_prefork php5
sudo a2enmod mpm_event
sudo service apache2 restart
sudo service php5-fpm restart

再起動時の注意点

今まではApacheとPHPが一体で動いていたので、PHPの設定を変更した際は
「sudo service apache2 restart」だけで良かったのですが

CGIで動かすと言う事は別のプロセスが動くと言う意味なので、PHPの設定を変更した際に
「sudo service php5-fpm restart」でphpを再起動する必要があります。

切り替えた後は

Apacheがeventに切り替わったかどうかは「sudo apache2ctl -V | grep 'MPM'」で確認できます。
eventに切り替わっていると「Server MPM: event」と表示されるはずです。

PHPが正しくFastCGIになったかはphpinfo();で確認して下さい。
正しく設定されていると「Server API」の項目が「FPM/FastCGI」になっているはずです。
apache-switch_to_event_001

実際にブラウザからアクセスしてみて、あなたのサイトが正しく表示されるか確認しましょう。
正しく表示されていれば設定完了です、何かエラーが出る時はエラーログを元に修正して下さい。

どうでも良いですが、PHPをFPM/FastCGIに切り替えると、HTTP300の時にファイル候補としてセットされる
「$_SERVER['REDIRECT_VARIANTS']」が「$_SERVER['REDIRECT_REDIRECT_VARIANTS']」になります。

バグ……なのかな?、こんな変数使う事滅多に無いから気付かれてない?
まぁ、配列のキーが変わっただけで中身は同じなので気にする必要ないとは思います。

 - サーバー