モヒカンメモ

髪色が定期的に変わることに定評のある(比較的)若者Webエンジニアの備忘録

php-fpmはリクエストが中断されても処理中のプログラムを中断しない

nginxでリクエストを受けてphp-fpmにpassするというPHPアプリケーションではスタンダードな構成において、リクエストが中断されたときphp-fpmの処理って中断されるんだっけ?されないんだっけ?というのが気になったので調べた。

ざっくりまとめ

  • クライアントがリクエストを中断すると、WebサーバはFCGI_ABORT_REQUESTレコードを発出する
  • php-fpmではFCGI_ABORT_REQUESTレコードをサポートしていない
  • 先の理由のため、クライアントがリクエストを中断してもphp-fpmが処理中のプログラムは中断されない

f:id:pinkumohikan:20201119020348p:plain
PHP

FastCGIとphp-fpm

nginxはクライアントからリクエストを受け取ると待機しているphp-fpmプロセスへFastCGIという仕様に基づいて処理を依頼する。

ja.wikipedia.org

php-fpmはPHPのFastCGI実装で、nginxより依頼されたCGI処理を行って結果をnginxへ返す。

www.php.net

FCGI_ABORT_REQUESTレコード

クライアントからのリクエストが中断される (コネクションが切れる) と、nginxから FCGI_ABORT_REQUEST レコードが発出される。

fastcgi-archives.github.io

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はそれを無視して処理を続行する。

github.com

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

stackoverflow.com

@yowatari