PHP-FPM徹底解説:仕組み・設定・チューニング・運用ベストプラクティス
はじめに — FPMとは何か
FPM(FastCGI Process Manager、一般的には「PHP-FPM」と呼ぶ)は、PHP アプリケーションを FastCGI として実行・管理するためのプロセスマネージャです。主に Nginx と組み合わせて使われ、従来の mod_php に比べてプロセス管理やパフォーマンス面、セキュリティ面で多くの利点があります。本コラムでは PHP-FPM の仕組み、主要設定、チューニング、運用上の注意点、トラブルシューティングまで深掘りします。
基本的なアーキテクチャ
PHP-FPM はマスター(親)プロセスと複数のワーカ(子)プロセスで構成されます。マスタープロセスは設定の読み込み、ワーカプロセスの起動・監視を行い、ワーカは実際に PHP スクリプトを処理します。Web サーバ(例:Nginx)は FastCGI プロトコルで PHP-FPM にリクエストを渡します。通信は UNIX ドメインソケット(例:/run/php/php7.4-fpm.sock)か TCP ソケット(例:127.0.0.1:9000)が使えます。
重要な設定項目(pool.d/*.conf)
主に /etc/php/*/fpm/pool.d/ 以下にプールごとの設定があります。代表的なディレクティブは以下の通りです。
- listen — 接続先ソケット(UNIX ソケットか IP:PORT)
- user / group — ワーカの実行ユーザ/グループ
- pm — プロセスマネージャのタイプ(static / dynamic / ondemand)
- pm.max_children — 同時起動できる最大ワーカ数(重要)
- pm.start_servers, pm.min_spare_servers, pm.max_spare_servers — dynamic 用の起動/スパーサーバ数
- pm.process_idle_timeout — ondemand 用のアイドル終了時間(例えば 10s)
- pm.max_requests — 子プロセスが再生成されるまでに処理するリクエスト数(メモリリーク回避に有効)
- request_terminate_timeout — リクエストの最大実行時間(タイムアウトでプロセスを終了)
- request_slowlog_timeout, slowlog — スローログの検出と保存先
- access.log, catch_workers_output — ワーカの標準出力/エラーをログに残す設定
pm のモード比較と選び方
pm 設定は運用負荷とリソースに合わせて選びます。
- static — 常に pm.max_children のプロセスを常駐させる。メモリが十分で、ピークが予測しやすい環境に向く。
- dynamic — pm.start_servers で起動し、需要に応じて pm.min_spare_servers〜pm.max_spare_servers の範囲で増減。汎用的で多くのケースに適合。
- ondemand — リクエストが来た時にプロセスを起動し、アイドル時に終了。アイドル期間が長いサーバや少ないメモリで運用する場合に有効だが、初回リクエストで起動遅延が発生する。
チューニングの考え方(実例を含む)
最も重要なのは pm.max_children の決定です。1つの大雑把な算出式:
- pm.max_children ≒ floor((総利用可能メモリ - OS および他プロセスの必要メモリ) / 1プロセスあたりの平均メモリ)
1プロセスあたりの平均メモリは、実運用で top/ps や smem、またはツールで測定します。OPcache や拡張モジュールは共有メモリを使うため、単純に RSS を足すだけでは過小評価する場合があります。
その他のポイント:
- pm.max_requests を設定して長時間動作によるメモリリークを緩和する(例:500〜10000)。
- request_terminate_timeout を設定してハングするリクエストを自動終了させる(例:30s〜300s、アプリに合わせる)。
- opcache を有効にして PHP の初期化時間とメモリを改善する。ただし opcache のメモリはプロセス間で共有される。
- listen を UNIX ソケットにするか TCP するか:同一ホストで稼働する場合は UNIX ソケットが高速でファイルパーミッション管理に優れる。複数サーバで PHP-FPM を分散する場合は TCP(IP:PORT)を使う。
Nginx と連携する基本設定例
代表的な Nginx の fastcgi 設定(抜粋):
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
UNIX ソケットを使う場合は socket の所有者・パーミッション(listen.owner, listen.group, listen.mode)を正しく設定し、Nginx の worker ユーザと一致させるかアクセス可能にしておきます。
監視・ステータス取得
PHP-FPM はステータス機能(pm.status_path)や ping 機能を持ち、稼働中のプロセス数、idle/active、リクエスト数などを返すことができます。Nginx 側で専用 location を作り、内部リクエストで取得して監視ツール(Prometheus など)に渡す構成が一般的です。外部に露出させる場合は必ず IP 制限や認証をかけてください。
Prometheus 連携には php-fpm 用の exporter(例:php-fpm_exporter)を使うとメトリクス収集が容易です。
運用でよくある問題と対処法
- 502 Bad Gateway — 原因は php-fpm が落ちている、ソケットパス不一致、socket パーミッション、または pm.max_children を超えてワーカが割り当てられていること。まず php-fpm の状態、ログ(error_log、pool の slowlog)を確認する。
- メモリ枯渇/OOM — pm.max_children が多すぎる可能性。上記の算出式で見直す。コンテナ環境では cgroup メモリ制限に注意。
- ハングや長時間処理 — request_terminate_timeout や slowlog を設定し、原因となるスクリプトを特定する。
- ログの急増 — catch_workers_output や access.log の設定により大量ログが出るとディスクを圧迫するため、ローテーションやログレベルを見直す。
セキュリティ面の考慮
主要ポイント:
- プールごとに user/group を分けて権限分離する(例:アプリごとに異なるユーザ)。
- listen.socket のパーミッション(listen.owner/group/mode)を適切に設定し、Nginx 以外からのアクセスを制限する。
- 外部にステータスや管理エンドポイントを公開しない。内部ネットワークや IP 制限、認証を必ず設ける。
- 必要があれば chroot や open_basedir、disable_functions など PHP 側の制限を検討する。
コンテナ化・クラウドでの運用
コンテナ環境では一つのコンテナに PHP-FPM を単体で動かすケースが一般的です。systemd は不要で、フォアグラウンドで起動(--nodaemonize)します。メモリ制限はコンテナの上限に連動するため、pm.max_children はコンテナメモリに合わせて算出してください。また、ロギングは stdout/stderr に出すか外部ログドライバで集約するのが運用上楽です。
ベストプラクティスまとめ
- まずは本番に近い負荷でワーカあたりの実メモリ消費量を計測し、pm.max_children を算出する。
- pm.max_requests と request_terminate_timeout を設定し、長時間運用でのメモリ膨張やハングを防ぐ。
- ステータスや slowlog を有効にして監視・アラートを整備する。
- UNIX ソケットを使う場合はパーミッション管理に注意。TCP はネットワークの設定を慎重に。
- 設定変更はまずステージングで検証し、systemctl reload などで停止を伴わず反映する(再起動は簡易だが短時間の接続断が発生するため計画的に)。
設定例(プール)
[www]
user = www-data
group = www-data
listen = /run/php/php7.4-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
request_terminate_timeout = 300s
php_admin_value[error_log] = /var/log/php7.4-fpm.log
php_admin_flag[log_errors] = on
おわりに
PHP-FPM は PHP を高負荷下で安定稼働させるための重要なコンポーネントです。設定は単にドキュメントのデフォルトを使うだけでなく、実際のアプリケーション特性(メモリ消費、リクエストの処理時間、トラフィックの波)に合わせて調整する必要があります。監視とログの整備、段階的なチューニングを行えば、可用性とパフォーマンスを両立できます。
参考文献
- PHP: PHP-FPM(公式マニュアル)
- PHP: Process Management(pm 設定)
- Nginx: ngx_http_fastcgi_module(公式ドキュメント)
- php-fpm_exporter(Prometheus 用エクスポーターの例)
投稿者プロフィール
最新の投稿
書籍・コミック2025.12.19漫画の現在地――歴史・制作・市場・未来を読み解くコラム
家電2025.12.19黒物家電を読み解く:歴史・技術・買い方・環境対策までの完全ガイド
ゲーム2025.12.19MSX徹底解説:歴史・仕組み・名作と現在の活用法
書籍・コミック2025.12.19ロマンス小説の魅力と書き方――読者を惹きつける感情曲線と市場戦略

