我有一个长时间运行的脚本,无缘无故地消失了。它应该运行超过8小时,但一两个小时后就会消失,没有错误,什么都没有。我尝试通过CLI和http运行它,没有区别。
我设置了以下参数:
set_time_limit(0);
ini_set('memory_limit', '1024M');
我一直在监视内存使用情况,并且它不会超过200M
还有什么我想念的吗?为什么会消亡?
答案 0 :(得分:6)
一种可能的解释可能是PHP垃圾收集器干扰了脚本。这可能就是你看到随机死亡的原因。当垃圾收集器打开时,只要根缓冲区运行满,就会执行循环查找算法。
启用和关闭机制以及自行启动循环收集的能力背后的基本原理是,应用程序的某些部分可能具有高度时间敏感性。
您可以尝试使用gc_disable
禁用PHP垃圾回收器。手册建议您在禁用释放缓冲区之前立即调用gc_collect_cycles
。
另一种解释可能是代码本身。一个8小时的脚本是一个很长的脚本,如果它很复杂,很容易遇到导致脚本退出的障碍。我认为,对于您现在的问题排查,您绝对应该将错误报告转为使用error_reporting(-1);
报告所有内容。
此外,如果您的脚本正在与其他服务进行通信,例如数据库,那很可能是问题所在。如果数据库服务器内存不足或超时,则可能导致脚本挂起并死机。如果是这种情况,您可以拆分与数据库的连接,并在脚本期间以特定的时间间隔连接/断开连接以保持新连接。同样的心态可以应用于您可能正在与之沟通的任何其他服务。
出于测试目的,您可以故意让您的脚本在每个成功的查询中写入日志文件,确保包含查询生成时的时间戳和查询结束时的时间戳。您可能不会收到任何错误,但它可以帮助您确定是否存在特定的问题查询,或者查询是否挂起的时间比平时长。您还可以检查以确保您的MySQL连接仍然有效,并打印出一些信息通知您。
示例日志文件:
[START 2011/01/21 13:12:23] MySQL Connection: TRUE [END 2011/01/21 13:12:28] Query took 5s
[START 2011/01/21 13:12:28] MySQL Connection: TRUE [END 2011/01/21 13:12:37] Query took 9s
[START 2011/01/21 13:12:39] MySQL Connection: TRUE [END 2011/01/21 13:12:51] Query took 12s
答案 1 :(得分:0)
这可能与代码有关。
我的脚本运行数周和数月没有任何问题。
您的数据库连接可能会超时并输出错误。 如果打开连接或文件,也可能会耗尽filedescriptors。或者你的共享内存区域已满。这取决于代码。
查看selinux没有弄乱你的系统日志。这样您的脚本就不会打印任何错误。从系统日志中,您还可以看到是否对任何系统资源都有用户限制(请参阅ulimit)。
如果你在cli中运行它并且你什么也得不到,甚至不是段错误,这真的很奇怪。你看到了stdout和stderr?
答案 2 :(得分:0)
也许它是segafults。 尝试以这种方式启动脚本:
$ ulimt -c unlimited
$ php script.php
看看是否在运行目录中找到核心转储文件(core.xxxx)
答案 3 :(得分:-1)
Apache也有自己的脚本超时,你需要调整httpd.conf文件