在 PHP-FPM 的池配置文件(通常是 www.conf)中设置 request_terminate_timeout 参数,可以强制终止运行超过指定秒数的脚本,防止单个慢脚本占满所有 worker 进程导致服务不可用。该配置优先于 php.ini 中的 max_execution_time,适用于 CGI/FPM 环境。
先说结论:配置 request_terminate_timeout 是防止 PHP-FPM 进程池因脚本死锁或长时间运行而耗尽的有效手段,能在进程层面回收资源。
- 适合:PHP-FPM 模式下防止 worker 进程被慢脚本占满的场景。
- 先准备:确认业务脚本的最大正常执行耗时,避免误杀合法长任务。
- 验收:通过 sleep 测试脚本验证超时终止是否生效,并检查错误日志。
命令速用版
在池配置文件中添加或修改以下参数,然后重载服务。
request_terminate_timeout = 30s重载命令示例(根据实际服务名调整):
systemctl reload php-fpm为什么会这样
PHP-FPM 的 request_terminate_timeout 是在进程管理器层面强制杀死脚本,而 php.ini 中的 max_execution_time 仅在脚本执行层面抛出错误。
当脚本因数据库锁、外部 API 超时或死循环卡住时,max_execution_time 可能无法及时释放进程资源,导致 FPM 子进程处于僵死状态。设置 FPM 层面的超时能确保操作系统层面回收该进程,防止连接池耗尽。
分步处理
1. 找到池配置文件,常见路径为 /etc/php-fpm.d/www.conf 或 /etc/php/8.x/fpm/pool.d/www.conf。
2. 搜索 request_terminate_timeout,取消注释并设置秒数,例如 request_terminate_timeout = 30s。
3. 执行语法检查命令 php-fpm -t 或 php-fpm -tt 确保配置无误。
4. 重载 PHP-FPM 服务,避免直接 kill 导致当前请求中断。
怎么验证是否生效
创建一个包含 sleep 函数的测试脚本,例如 sleep(40),然后通过浏览器访问。
如果配置为 30 秒,请求应在 30 秒后被切断,返回 502 Bad Gateway 或 504 Gateway Time-out。
检查 PHP-FPM 错误日志,通常位于 /var/log/php-fpm/error.log,确认是否有脚本终止记录。
常见坑
1. 设置过短:正常业务逻辑(如大文件导出)可能超过阈值,导致合法请求被杀。
2. 配置未生效:修改了 php.ini 而非 FPM 池配置,或者修改后未重载服务。
3. CLI 模式无效:该参数仅对 FPM SAPI 生效,命令行脚本不受此限制。
常见问题
request_terminate_timeout 和 max_execution_time 有什么区别?
max_execution_time 是 PHP 脚本层面的限制,抛出 fatal error;request_terminate_timeout 是 FPM 进程层面的限制,直接杀死进程。
超时后日志在哪里查看?
主要查看 PHP-FPM 的错误日志,路径通常在 php-fpm.conf 中配置的 error_log 项,常见于 /var/log/php-fpm/ 目录。
这个配置会影响 CLI 脚本吗?
不会,request_terminate_timeout 仅适用于 PHP-FPM 模式,命令行运行的 PHP 脚本不受此参数控制。
参考来源
PHP.net - FPM Configuration: https://www.php.net/manual/en/install.fpm.configuration.php