nginxでリクエストを受けてphp-fpmにpassするというPHPアプリケーションではスタンダードな構成において、リクエストが中断されたときphp-fpmの処理って中断されるんだっけ?されないんだっけ?というのが気になったので調べた。
nginx x php-fpm構成で、requestがabortされたときってphpの処理もinterruptされるんだっけ
— ぴんくもひかん (@pinkumohikan) 2020年9月30日
ざっくりまとめ
- クライアントがリクエストを中断すると、WebサーバはFCGI_ABORT_REQUESTレコードを発出する
- php-fpmではFCGI_ABORT_REQUESTレコードをサポートしていない
- 先の理由のため、クライアントがリクエストを中断してもphp-fpmが処理中のプログラムは中断されない
FastCGIとphp-fpm
nginxはクライアントからリクエストを受け取ると待機しているphp-fpmプロセスへFastCGIという仕様に基づいて処理を依頼する。
php-fpmはPHPのFastCGI実装で、nginxより依頼されたCGI処理を行って結果をnginxへ返す。
FCGI_ABORT_REQUESTレコード
クライアントからのリクエストが中断される (コネクションが切れる) と、nginxから FCGI_ABORT_REQUEST
レコードが発出される。
5.4 FCGI_ABORT_REQUEST
The Web server sends a FCGI_ABORT_REQUEST record to abort a request.
A Web server aborts a FastCGI request when an HTTP client closes its transport connection while the FastCGI request is running on behalf of that client.
php-fpmはFCGI_ABORT_REQUESTレコードをサポートしていない
少なくとも PHP 7.4.12 に付随するphp-fpmでは FCGI_ABORT_REQUEST
レコードをサポートしていない。そのため、Webサーバ (nginx) がクライアントとのコネクション切断を検知するなどして FCGI_ABORT_REQUEST
レコードを発出したとしても、php-fpmはそれを無視して処理を続行する。
FCGI_ABORT_REQUEST = 2, / [in] (not supported) /
かんたんなテストでもphp-fpmによる処理は中断されないことを確認した (10秒後にログを書き込みレスポンスを返すAPIを用意して、クライアントからリクエスト後、10秒経つ前にリクエストを中断してみた)。
まだ分かっていないこと、関連する疑問
- apache モジュール版PHPで動かすと中断された気がするが、認識は合っているか
- php-fpmでFCGI_ABORT_REQUESTをサポートしていない背景、サポートする予定はないのか
- php-fpm以外のFastCGI実装はあるのか
知っている人がいれば是非教えて欲しい。
Special thanks
@Danack
@yowatari
FCGI_ABORT_REQUEST の対応かな。php-fpmは対応ないっぽい
— 武田あやな (@yowatari) 2020年9月30日