nginx + php で504 Gateway Timeout(タイムアウト)設定あれこれ

はじめに

少し重い処理を実行した時におよそ1分で「504 Gateway Timeout」が発生。タイムアウトの時間をもっと長く設定する方法を調べてみた。

PHPの設定

/var/php.ini

設定項目

max_execution_time = 30

数値はデフォルト値

phpスクリプト自身の実行時間。sleep()関数やファイルアップロードにかかる時間、データーベース間で発生する処理時間などは含まれない。処理が複数ファイル間で実行されている場合などはそれぞれのスクリプトで適応されるのでタイムアウトしない事もある。

php-fpm.conf

設定項目

request_terminate_timeout 0

数値はデフォルト値 0はOFFの意味

max_execution_timeで処理をkillできなかった場合に発動する。

設定の反映

PHP側のみ設定しても、NGINX側の設定がボトルネックになる場合がある。

NGINXの設定

/etc/nginx/nginx.conf

設定項目

fastcgi_connect_timeout 60;
fastcgi_send_timeout 60;
fastcgi_read_timeout 60;

proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 60;

send_timeout 60;
keepalive_timeout 75;

数値はデフォルト値

  • fastcgi_○○は、nginxとphpでのやりとりの時間。はじめにconnectしてからリクエストをsend、応答を待つ時間がreadなので、php側で重い処理をする場合などはfastcgi_read_timeoutのみ設定すればいける。
  • proxy_○○は、nginxをプロキシサーバとして使っている場合に設定。
  • send_timeoutは、クライアント間でのタイムアウト時間。
  • keepalive_timeoutは、クライアントとの接続をキープする時間。

設定の反映

まとめ

ブラウザから送られたリクエストがサーバで処理されて返ってくるまでに意外とたくさん経由しているので、それぞれのタイムアウト時間を考えなければいけなかった。

上記の設定を必ずしもすべて設定する必要はなく、今回は、「nginx.conf」のfastcgi_read_timeoutのみを長めに設定したらタイムアウトしなくなった。

どこでタイムアウトしているか見極めて設定することが大切ですね。AWSのELBを使っている場合はそちらにもタイムアウト関連の設定があったり、インフラって難しい。。。