我正在尝试运行一个较长的 php 进程,但最后出现了 500 内部服务器错误。它运行良好,大约持续了 8 分钟。更改 php 设置后,我重启了机器。
PHP配置:
最大执行时间:3600
大约10分钟后 ps ax|grep php:
19007?S 0:08 /usr/bin/php /home/gypsy/public_html/index.php
我已将 ignore_user_abort 设置为 true。
该进程卡在00:08(第8分钟)并且不再进一步执行。
Apache 错误日志显示错误:
脚本在返回标题之前超时:index.php
似乎 max_execution_time 不起作用。任何建议都会很有帮助。
更新:
我已经能够检测到问题。是防火墙阻止了该进程。服务器正在使用 iptables 和 configserver 作为防火墙。禁用防火墙可以正常工作。但我不确定要更改哪些设置才能允许防火墙中的长时间运行的进程
答案1
每当我看到“标题”错误时,我都会检查是否
- 有任何输出缓冲处于活动状态
- 已经生成了任何标头
在代码中可能发生任何故障和/或转发之前。最后的办法有时是逐步执行脚本的各个阶段,如下所示:
var_dump($runtimeStuffInfo);die('argh!');
并缩小问题开始发生的区域代码。
你没有完全说明你的“8 分钟脚本”试图做什么,但根据我的经验,最稳定的方法是坚持使用 CLI 来处理这类事情:
理想情况下,您可以通过 SSH 登录到您的服务器并从命令行运行脚本(最好通过 nohup,这样您就不必关心连接是否中断) - 这样您还可以始终看到脚本停止的位置(如果它仍然会停止),因为您可以立即记录每个位,因为它会回显到控制台。
如果你没有通过 SSH 登录的权限,你仍然可以尝试exec ('nohup php long_running_job.php > /some/writable/directory/with766/your_job.log')
在一个 PHP 页面中触发你的作业(例如http://example.com/startjob.php),然后在另一个脚本页面中解析 your_job.log 中 cronjob 的输出(例如http://example.com/jobresults.php)。
如果以上所有方法都无法帮助您实现目标,我会将工作分解为几个较小的工作块,这些工作块将在超时问题发生之前完成,然后一个接一个地调用它们。
答案2
set_time_limit(3600) 怎么样;
在你的脚本开头?这样可行吗?
答案3
FCGI 是 apache 处理程序吗?如果是,那么您必须将 FcgidIOTimeout 和 FcgidBusyTimeout 设置为更高的值。您可以在加载 fcgi 模块后将这些指令放在 apache 配置文件中(或在某些情况下放在 fcgi.conf 或 php.conf 中)。您可以在 apache fcgi 文档中找到更多信息http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html