Nginx + PHP FPMの仕組み


Nginxの基本知識


Nginxとは

・シングルスレッド、非同期、イベント駆動のWebサーバ
・スレッドはプロセスとして独立しておりマルチプロセスで動作可能
・軽量的な実装
・ロードバランシング、キャッシュなどプロキシとしての利用も可能


Nginxのライフサイクル

・masterプロセスがコンフィグの読み込みとポートのバインドを行う
・masterプロセスがworkerプロセスを立ち上げる
・workerがlisteningを開始しリクエストを処理する
・configが再読込みされると新しいworkerを作成し古いworkerと入れ替える
・masterプロセスが落とされ処理が終了する



Nginxのworker

・Webサーバとしての処理のすべてを担う
・workerはシングルスレッドで動作する
・IOイベントのシステムコールとしてepoll, kqueueなどを利用する

events {
    use epoll;
}


ProxyとしてのNginx

クライアントのリクエストをupstreamへ中継する
・Reverse Proxy(Ruby on Railsなど)
・FastCGI Proxy(PHP FPMなど)


NginxのFastCGI Proxing



PHP FPMの基本知識


PHP FPMとは

・PHP FastCGI Proccess Manager
・FastCGIインタフェースをもったPHP実行環境
・Nginxから見たPHP実行サーバ



NginxとPHP FPMの接続


Nginxの設定

location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
}


静的ファイル取得の流れ



PHPファイル取得の流れ



よく見るNginxのエラー


"Primary script unknown" while reading response header from upstream

・ PHP FPMが指定されたPHPファイルを見つけられない



-> 存在しないパスが指定されてないか確認する


client intended to send too large body

・ クライアントからPOSTされたデータが大きすぎる



-> Nginxのupload_max_filesizeを調整する
-> php.iniのpost_max_sizeを調整する
-> php.iniのupload_max_filesizeを調整する

-> Nginxのclient_body_buffer_sizeは関係ない
-> Nginxのfastcgi_buffer_sizeは関係ない


a client request body is buffered to a temporary file

・クライアントからのリクエストボディがメモリバッファの容量を超えているためテンポラリファイルに書き込みをおこなった


-> 状況は"client intended to send too large body"と似ていてクライアントから送られてきたデータの大きさの問題
-> Nginxのclient_body_buffer_sizeを調整する


upstream sent too big header while reading response header from upstream

・PHP FPMのレスポンスヘッダーが大きすぎる



-> Nginxのfastcgi_buffer_sizeを調整する
-> PHPアプリが大きなレスポンスヘッダー(クッキーなど)を返してないか確認する


upstream timed out

・ PHP FPMから返事が返ってこない

<?php
  sleep(100000000000000);
?>


-> Nginxのfastcgi_read_timeoutを調整する
-> AWSのELBを使ってる場合はELBのIdle Timeoutも確認したほうがいいかも

-> php.iniのmax_execution_timeは関係ない
 * 上記が関係するエラーは "Fatal error: Maximum execution time of 60 seconds exceeded"


参考

Inside NGINX: How We Designed for Performance & Scale
The Architecture of Open Source Applications (Volume 2): nginx
Understanding and Implementing FastCGI Proxying in Nginx
PHP と SAPI と ZendEngine3 と - SlideShare
nginx でリバースプロキシする際は HTTP レスポンスヘッダーのサイズに注意
nginxのリクエストボディのバッファリングに関する問題とその改善策
PHPスクリプトの実行時間を制御する(max_execution_time) - hogehoge foobar Blog Style5
PHPでファイルをアップロードするときの設定 | maidsphere