我有一个PHP脚本,它从数据库中抓取一大块数据,对其进行处理,然后查看是否有更多数据。这个过程无限期地运行,我在一台服务器上一次运行其中几个。
它看起来像:
<?php
while($shouldStillRun)
{
// do stuff
}
logThatWeExitedLoop();
?>
问题是,经过一段时间后,某些事情导致进程停止运行,我无法对其进行调试并确定原因。
到目前为止,这是我用来获取信息的内容:
您会建议使用哪些其他调试方法来查找罪魁祸首?
注意:我应该补充一点,这不是max_execution_time 的问题,对于这些脚本是禁用的。被杀之前的时间是不一致的。它可以在它死亡之前运行10秒或12小时。
更新/解决方案:谢谢大家的建议。通过记录输出,我发现当MySql查询失败时,脚本被设置为die()。 D'哦。更新它以记录mysql错误然后终止。现在就像魅力一样工作!
答案 0 :(得分:2)
请记住,PHP在ini文件中有一个变量,表示脚本应该运行多长时间。 max-execution-time
确保您没有检查过,或使用set_time_limit()来增加执行时间。该程序是通过Web服务器还是通过cli运行的?
添加:我使用PHP的糟糕体验。查看我今年早些时候写的一些背景脚本。抱歉,PHP是一种糟糕的脚本语言,可以在很长一段时间内完成任何操作。我看到较新的PHP(我们尚未升级到)添加了强制GC运行的功能。我一直遇到的问题是使用太多的内存,因为GC几乎从不运行来清理自己。如果你使用递归引用自己的东西,它们也永远不会被释放。
创建一个包含100,000个项目的数组会产生内存,但是然后将数组设置为空数组或将其全部拼接出来,不会立即将其释放,并且不会将其标记为未使用(也就是说新的100,000个元素数组会增加存储器)。
我个人的解决方案是写一个永远运行的perl脚本和system(“php my_php.php”);在需要时,解释器将完全释放。我目前支持5.1.6,这可能会在5.3+或至少修复,现在他们有GC命令可以用来强制GC清理。
简单脚本
#!/usr/bin/perl -w use strict; while(1) { if( system("php /to/php/script.php") != 0 ) { sleep(30); } }
然后在你的PHP脚本
<?php // do a single processing block if( $moreblockstodo ) { exit(0); } else { // no? then lets sleep for a bit until we get more exit(1); } ?>
答案 1 :(得分:2)
我会记录脚本的内存使用情况。也许它获得了太多的内存,达到了内存限制并且死了?
答案 2 :(得分:0)
我将函数的状态记录到每个循环中几个不同位置的文件中。
您可以使用var_export($varname,true)
表单将大多数变量的内容作为包含var_export的字符串。
您可以将其记录到某个文件中,并密切关注它。日志结束前函数的最新状态应提供一些线索。
答案 3 :(得分:0)
听起来无论发生什么都不是标准的php错误。您应该能够使用try ... catch语句抛出自己的错误,然后记录该语句。除此之外我没有更多细节因为我在手机上远离电脑。
答案 4 :(得分:0)
我之前在我们的一个工作项目中遇到过这个问题。我们有类似的设置 - 如果有任务要完成,PHP脚本会检查数据库(例如发送电子邮件,更新记录,处理一些数据)。 PHP脚本里面有一个while循环,设置为
while(true) {
//do something
}
过了一会儿,剧本也会以某种方式被杀死。我已经尝试了大部分已经说过的内容,例如设置max_execution_time,使用var_export记录所有输出,放置try_catch,制作脚本输出(php ...&gt; output.txt)等我们从来没有能够找出问题所在。
我认为PHP本身不是为了完成后台任务而构建的。我知道它没有回答你的问题(如何调试),但我们的工作方式是我们使用cronjob每5分钟调用一次PHP文件。这类似于Jeremy使用perl脚本的答案 - 它确保解释器在执行完成后是免费的。
答案 5 :(得分:0)
如果这是在Linux上,请尝试查看系统日志 - 该过程可能被OOM(内存不足)杀手杀死(不太可能,如果发生这种情况,您也会看到其他问题),或者分段错误(某些版本的PHP不喜欢某些版本的扩展,导致奇怪的崩溃)。