查找PHP脚本终止源的最佳实践

Nat*_*ner 6 php apache debugging

我有一个PHP脚本,它从数据库中抓取一大块数据,对其进行处理,然后查看是否有更多数据.这个进程无限期地运行,我在一台服务器上一次运行其中几个.

它看起来像:

<?php
    while($shouldStillRun)
    {
       // do stuff
    }
    logThatWeExitedLoop();
?>
Run Code Online (Sandbox Code Playgroud)

问题是,经过一段时间后,某些事情导致进程停止运行,我无法调试它并确定原因.

以下是我到目前为止获取信息的方法:

  • error_log - 记录所有错误,但错误日志中不显示任何错误.
  • register_shutdown_function - 注册了自定义关闭功能.这确实被调用,所以我知道进程没有被服务器杀死,它被允许完成. (或者至少我认为这是被称为的情况?)
  • debug_backtrace - 在我的自定义关闭函数中记录了debug_backtrace().这只显示一个调用,这是我的自定义关闭功能.
  • 记录如果到达脚本的末尾 - 在循环之外,我有一个函数记录脚本退出循环(因此将正常到达源文件的末尾).当脚本随机死亡时,它不会记录这个,所以无论什么杀死它,都会在处理过程中杀死它.

你会找到什么其他的调试方法来找到罪魁祸首?

注意:我应该补充一点,这不是max_execution_time的问题,对于这些脚本禁用了max_execution_time.被杀之前的时间是不一致的.它可能会在它死亡之前运行10秒或12小时.


更新/解决方案:谢谢大家的建议.通过记录输出,我发现当MySql查询失败时,脚本被设置为die().D'哦.更新它以记录mysql错误然后终止.现在就像魅力一样工作!

Rah*_*hly 2

请记住,PHP 在 ini 文件中有一个变量,用于指示脚本应运行多长时间。最大执行时间

确保您不会超过此范围,或使用 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

使用严格;

而(1){
  if( 系统("php /to/php/script.php") != 0 ) {
    睡觉(30);
  }
}

然后在你的 php 脚本中

<?php

// 执行单个处理块

如果($moreblockstodo){
  退出(0);
} 别的 {
  // 不?然后让我们睡一会儿直到我们得到更多
  退出(1);
}

?>