CentOS7にApache2.4.6(event_mpm)+PHP-FPM環境の構築

Apache2.4.1からEvent MPMが正式に採用されたので、Apacheをイベント駆動型で動かすことが出来るようになりました。なんだか同時に高速の処理が出来るらしいとのことで速そうです。

参考:Apache_MPMに係る設定 | 静岡大学 横山研究室

今回新しくCentOS7にApache2.4.6を入れたので、チューニングが難しそうですが、せっかくだからとMPMをEventに変更して環境構築してみようと思いました。
インストール方法によってはデフォルトでEventになっているようですが、yumからインストールするとPreforkでした。

また、Event MPMの時はPHPをモジュールモードではなくFCGIで動かすのが推奨とのことですので、PHP-FPMを導入し、Apache2.4.6(event_mpm)+PHP-FPM(PHP7.0.3)の構成を目指します。

事前準備 リポジトリの追加

PHP7などを入れるので、事前にリポジトリを追加しておきます。
とりあえずepelとremiを入れます。

# epelリポジトリの追加
yum install -y epel-release
# remiリポジトリの追加
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

Apacheのインストール

CentOS7で普通にyumインストールすると、2.4.6が入るようです。
本当はyumではなくソースからビルドしてもっと新しいVerを入れたほうがいいのかもしれませんが、yumで一元化したかったのでこのままということで。

yum install httpd httpd-devel

Apache2.4系からなのか、confファイルは色々分散してインストールされます。

#メインのconfファイル
/etc/httpd/conf/httpd.conf

#モジュールをロードするconfファイルが入るディレクトリ
/etc/httpd/conf.modules.d/
 … ここに色々入ってる

#その他の色々なconfファイルが入るディレクトリ
/etc/httpd/conf.d/
 … ここにも色々入る

httpd.confに全部書いてあったことが分散してますね。
モジュールのロードに関して、要らないものを外すとか、追加したものをロードする時とかに conf.modules.dの中身を確認し、モジュールに対しての設定や、その他諸々をconf.dの中に入れてしまう感じですね。
VirtualHostの設定なんかも、confファイルを個別に作ってconf.dに入れてます。

Apacheの起動と、自動起動の登録はこちらのコマンドを実行します。

# 自動起動を設定
systemctl enable httpd.service

# 起動コマンド
systemctl start httpd.service

また、何か設定を変更して反映したい時は、restartでもいいのですが、reloadの方が一瞬で終わるのでこちらの方が良いみたいです。

systemctl reload httpd.service

ApacheをEvent MPMにする

MPMを変更するときは、こちらがMPMモジュールのロードのためのconfファイルになっているようなので、これを編集します。

vim /etc/httpd/conf.modules.d/00-mpm.conf

中身はこんな感じ。

# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:

# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so

mpm_prefork_module がロードされています。
コメントにある通り、これは3つのうちどれかしかロード出来ません。
mpm_prefork_moduleの方をコメントアウトし、mpm_event_module の方のコメントアウトを外します。

また、それぞれのチューニングに関する設定も追々必要になるはずです。

vim /etc/httpd/conf.d/mpm.conf

こんな感じのファイルを新規作成し、中にパラメータ設定を記述しておきます。

# Event
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
</Ifmodule>

これはデフォルトの値です。
ここからCPUやメモリ等のスペックと、PHPのプロセスのメモリ量等と相談しながら、ちょうどいい値を探っていく感じになります。とりあえず一旦はここまでです。
設定に問題がないか、Apacheを再起動して確認しておきましょう。

#apacheがどのMPMで起動しているかの確認
apachectl -V | grep 'Server MPM'

Server MPM: event
と出ていれば成功です。

PHPのインストール

PHPをインストールします。7.0を入れるにはremiリポジトリを指定します。

yum --enablerepo=remi-php70 install php php-devel php-opcache php-mbstring php-mcrypt php-mysqlnd php-gd php-pecl-apcu

わざわざ書かなくても一緒に入るものもありますが、php-opcacheやmbstring等も入れています。
php-develは書かないと入らないかもしれないです。
他、php-mysqldnと、php-gdはこのサイトでは必須なので入れました。また、php-pecl-apcuも使いたいので入れました。

php.iniについては色々あると思いますが、とりあえずこれだけは変えておこうというものがこちら。

#ヘッダに情報出さない
expose_php = Off

#送信系のサイズ指定
post_max_size = 36M
upload_max_filesize = 36M

# スクリプトのタイムアウト。ApacheのTimeoutに合わせて。
max_execution_time = 60

#タイムゾーン
date.timezone = "Asia/Tokyo"

Apacheは勝手にAsia/Tokyoになりましたが、こちらはそうではないみたい。
あと、PHPもモジュール系のiniファイルは/etc/php.d/ ディレクトリに配置されているので、opcacheやmysqlndのiniファイルについては例えばこんな感じのパスになります。

vim /etc/php.d/10-opcache.ini

ここまで来るとApacheの設定の方で、モジュールを読み込むようになっているはずです。
今回PHP-FPMで駆動させるので、モジュール読み込みは不要です。

vim /etc/httpd/conf.modules.d/15-php.conf

ここでモジュールを読み込んでいるので、このファイルごとリネームしておいたり、中身のLoadModuleをコメントアウトしたりしておきます。

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

こちらにはモジュール読み込み時のPHP関連設定があります。同様にリネームなどして退避しておきましょう。

PHP-FPMをインストール

PHPのインストールが完了しましたが、このままではApacheからPHPが動かせませんので、PHP-FPMをインストールします。
PHP-FPMはApacheの裏側で起動していて、ApacheにPHPファイルへのリクエストが来ると、内部のプロキシによって処理が渡され、PHP実行し結果を返すという構造になります。

PHPの設定もPHP-FPMでコントロールするので、php.iniの設定の反映等はPHP-FPMをリロードしないと反映しなくなったりします。

yum install --enablerepo=remi-php70 php-fpm

インストールはこれだけです。
PHP-FPMも、Apacheのように起動と自動起動登録をします。

systemctl start php-fpm
systemctl enable php-fpm

PHP-FPM自体の設定については、主に /etc/php-fpm.d/www.conf を編集します。
yumインストールだと、user:groupは自動的にapacheになっていましたが、Apacheの方で実行ユーザー・グループを変更していた場合は、こちらも合わせて変更します。

ApacheのProxyPass設定

さて、この状態だとApacheとPHP-FPMがそれぞれ勝手に起動しているだけなので、ApacheがPHPファイルのリクエストを受け取った時はPHP-FPMに渡すように、ProxyPassの設定をします。

例えば、VirtualHostの設定をしているディレクティブ内で下記のように記述すると、PHPファイルがPHP-FPMで処理されるようになります。
ついでに、phpMyAdminをインストールした時の記述も追加しました。

<VirtualHost *:80>
  ServerName examle.jp
  DocumentRoot /var/www/html
  
  # ProxyPassMatch でPHPファイルはfcgiに流すように指定
  ProxyPassMatch ^(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1 disablereuse=on

  # ついでにphpMyAdminを使う場合の設定
  ProxyPassMatch ^/phpmyadmin/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/usr/share/phpMyAdmin/$1 disablereuse=on
  ProxyPassMatch ^/phpmyadmin/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/usr/share/phpMyAdmin$1index.php disablereuse=on

  # バックエンド側へはKeepAliveしない 
  SetEnv proxy-nokeepalive 1
  # タイムアウト設定。無ければTimeoutの値になる。
  ProxyTimeout 60
  
  DirectoryIndex  index.php
</VirtualHost>

ProxyPassMatchのところで指定しているdisablereuse=onというのは、バックエンド側へのコネクションは再利用しないというパラメータです。

mod_proxy – Apache HTTP サーバ バージョン 2.2
※こちらは2.2のリファレンスですが…。

とりあえずこんな感じの設定をして、Apacheを再起動すると、PHPのページが表示出来るようになっているはずです。
phpinfo()で出てくるServer APIの項目が、FPM/FastCGIになっていれば、ちゃんとPHP-FPMで動いている証拠です。
(Apacheモジュールの時は、「Apache 2.0 Handler」になっています)

これで、Event MPMで動くApacheでPHPを使う環境が整いました。

コメント

タイトルとURLをコピーしました