目次
1. はじめに
CentOS 8 に用意されたパッケージを使って、Apache と PHP を導入・連携して動作させる場合に、この2つのアプリケーションがどのように関係しているのかについて説明します。
2. CentOS 8 での変更点
Apache には、「受け付けたリクエストをどのように処理するか」を決める MPM (Multi Processing Module) という設定項目があり、マルチスレッドで動作する “worker” や “event“、もしくはマルチプロセスで動作する “prefork” のどれかを指定しなければいけません。 Apache から PHP を連携させるために mod_php モジュールを利用する場合は、このモジュールが スレッドセーフな設計ではないために、”prefork” を選ぶ必要があります。このため、CentOS 7 までの Apache は デフォルトで “prefork” が選択されていました。ただ、マルチプロセスである prefork は時代遅れ感があり、いつまでこの設定を使い続けるんだろうという疑問はありました。
そして CentOS 8 での Apache では、MPM のデフォルト値が “event” になりました(*1)。こうなると mod_php は利用できないため、代わりに php-fpm が利用されることになりました。php-fpm は FastCGI という仕様を実装しており、Webサーバーとは別のプロセスとして常時稼働し、HTTPリクエストをWebサーバーから転送して貰って処理しレスポンスを返す、という使われ方をします。
Webサーバー側は「FastCGI として動作するプロセス」にリクエストを転送できればよく、プログラミング言語に依存しません。プログラミング言語側は FastCGI として動作するライブラリを用意しておけば、FastCGI に対応した Webサーバーから利用して貰うことができます。Apache の場合は、FastCGI にリクエストを転送するために、mod_proxy_fcgi というモジュールが用意されています。
*1: CentOS 8 の Apache は、HTTP/2 をサポートしているバージョンになりました。この HTTP/2 対応には、mod_http2 という Apache のモジュールが利用されるのですが、このモジュールに最適な MPM の選択肢ということで、event がデフォルトになったようです。Nginx でも php-fpm を使っていますし、mod_php が使われなくなったのは自然な流れであったと感じます。
3. CentOS 8 の Apache と PHP を観察する
CentOS 8 上でパッケージからインストールした Apache と PHP について観察します。
(1) インストール
以下のコマンドで、Apache と PHP をインストールしました。
sudo dnf install httpd php
- php-fpm パッケージも合わせてインストールされたようです(phpパッケージから「弱い依存関係」が設定されているようです)。
- この後、
/etc/httpd/conf/httpd.conf
ファイルを少し変更したり、firewall の設定を変更したりしました。
(2) 動いているサービス
Apache が動いています。
$ sudo systemctl status httpd.service
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Drop-In: /usr/lib/systemd/system/httpd.service.d
└─php-fpm.conf
Active: active (running) since Tue 2020-07-13 21:58:29 JST; 2 weeks 6 days ago
Docs: man:httpd.service(8)
Process: 70840 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)
Main PID: 824 (httpd)
Status: "Total requests: 2965; Idle/Busy workers 100/0;Requests/sec: 0.00165; Bytes served/sec: 25 B/sec"
Tasks: 278 (limit: 2848)
Memory: 23.7M
CGroup: /system.slice/httpd.service
├─ 824 /usr/sbin/httpd -DFOREGROUND
├─70859 /usr/sbin/httpd -DFOREGROUND
├─70860 /usr/sbin/httpd -DFOREGROUND
├─70861 /usr/sbin/httpd -DFOREGROUND
├─70862 /usr/sbin/httpd -DFOREGROUND
└─71082 /usr/sbin/httpd -DFOREGROUND
(省略)
php-fpm も動いています。
$ sudo systemctl status php-fpm.service
● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2020-07-13 21:58:29 JST; 2 weeks 6 days ago
Main PID: 825 (php-fpm)
Status: "Processes active: 0, idle: 6, Requests: 788, slow: 0, Traffic: 0req/sec"
Tasks: 7 (limit: 2848)
Memory: 34.7M
CGroup: /system.slice/php-fpm.service
├─ 825 php-fpm: master process (/etc/php-fpm.conf)
├─ 832 php-fpm: pool www
├─ 837 php-fpm: pool www
├─ 838 php-fpm: pool www
├─ 839 php-fpm: pool www
├─ 840 php-fpm: pool www
└─2013 php-fpm: pool www
(省略)
(3) Apache の関連モジュール
/etc/httpd/conf.modules.d/00-proxy.conf
ファイルで、mod_proxy とmod_proxy_fcgi が読み込まれています。
LoadModule proxy_module modules/mod_proxy.so
(省略)
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
(省略)
mod_proxy.so と mod_proxy_fcgi.so ファイルの実体は、/usr/lib64/httpd/modules/
にあります。
(4) MPMはどれになってる?
MPM が何になっているか確かめます。
まず、/etc/httpd/conf.modules.d/00-mpm.conf
ファイルを見てみます。
(省略)
# 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
Apache のモジュールを観察します。
$ sudo httpd -M | grep -i mpm
mpm_event_module (shared)
やはり、”event” になっています。
(5) Apache 側の php-fpm 設定箇所
クライアント(Webブラウザ)が送信してきた HTTPリクエストを Apache が受け付け、特定の条件に一致したリクエストを php-fpm に転送する設定は、/etc/httpd/conf.d/php.conf
に記述されています。以下に抜粋します。
#
# Redirect to local php-fpm (no mod_php in default configuration)
#
<IfModule !mod_php5.c>
<IfModule !mod_php7.c>
(省略)
<FilesMatch \.(php|phar)$>
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>
</IfModule>
</IfModule>
mod_php5 もしくは mod_php7 がない場合に、mod_proxy_fcgi が利用されるようです。
FilesMatch
のところを見ると、 UNIXドメインソケットを使ってプロセス間通信を行っているのがわかります。php-fpm のソケットファイル /run/php-fpm/www.sock
が指定されています。この書き方は、mod_proxy_fcgi – Apache HTTP Server Version 2.4 で紹介されている例とほぼ同じです。
「/run/php-fpm/www.sock
」というファイルパスは、/etc/php-fpm.d/www.conf
ファイル内で設定されています。
(6) php-fpm のファイル
php-fpm の設定ファイルは以下にありました。
/etc/php-fpm.conf
/etc/php-fpm.d/www.conf
起動中の php-fpm に関するファイルは以下にあります。
$ ls -alF /run/php-fpm/
合計 4
drwxr-xr-x 2 root root 80 7月 14 15:58 ./
drwxr-xr-x 31 root root 940 7月 14 15:58 ../
-rw-r--r-- 1 root root 3 7月 14 15:58 php-fpm.pid
srw-rw----+ 1 root root 0 7月 14 15:58 www.sock=
pidファイルや、先程出てきたソケットファイルが配置されています。
4. 参考
- Chapter 10. Using the PHP scripting language Red Hat Enterprise Linux 8 | Red Hat Customer Portal
- Chapter 1. Setting up the Apache HTTP web server Red Hat Enterprise Linux 8 | Red Hat Customer Portal
- マルチプロセッシングモジュール (MPM) – Apache HTTP サーバ バージョン 2.4
- mod_proxy_fcgi – Apache HTTP Server Version 2.4
- HTTP/2 guide – Apache HTTP Server Version 2.5
- mod_http2 – Apache HTTP Server Version 2.4
- PHP: FastCGI Process Manager (FPM) – Manual