2012-03-01 104 views
5

我有一个PHP cron作业运行29分钟后失败。在日志中的错误(/var/log/php_errors.log)是:PHP cron作业由于最大执行时间提前终止致命错误

[01-Mar-2012 00:32:57 UTC] PHP Fatal error: Maximum execution time of 60 seconds exceeded in /path/file.php on line 2079 

触发的cron crontab条目是:

00 00 * * * /usr/bin/php /path/file.php 

从我的研究,我不认为这是关系到max_execution_time配置设置,因为:

  1. 我知道一个事实,它运行了29:18分钟(即比错误消息多得多于60秒)。
  2. the PHP docs - 当在命令行运行PHP的默认设置为0

问:为什么脚本早终止?


注:

剧本是非常沉重的,而且会运行成千上万的数据库查询,但我跑top和CPU负荷率不高。

从错误日志中的线是mysql_query电话:

$sql = "SELECT SUM(amount) FROM mytab WHERE mem = '$id' AND validto > '$now'"; 
$res = mysql_query($sql); 

> php -v 
PHP 5.3.10 (cli) (built: Feb 2 2012 17:34:38) 
Copyright (c) 1997-2012 The PHP Group 
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies 
    with Suhosin v0.9.33, Copyright (c) 2007-2012, by SektionEins GmbH 

> cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 5.7 (Tikanga) 

更新 - 我找到了原因脚本可以29分钟的实时运行,但PHP可以退出引用执行时间低得多。

在任何时间用在这种情况发生的脚本的执行,例如系统调用使用系统(),流操作,数据库查询,等等确定该脚本已运行的最大时间时,不包含外活性。

(来自the set_time_limit() docs,但也在the max-execution-time docs中提及)。这对我来说很重要,因为大部分脚本都是长时间运行的db查询和支付API调用,而这些调用不会为执行时间计时。

+1

cron作业与您的错误无关,这是一个纯粹的PHP问题。检查内存泄漏,尝试在执行循环后取消设置一些错误数组。在查询之间设置免费的其他大变量。 – 2012-03-01 07:54:43

+0

您还会在文档中注意到:_最大执行时间不受系统调用,流操作等的影响。你能确定它实际上是由cron激发的PHP _CLI_吗? – 2012-03-01 07:57:10

+0

我也会检查你是否有合适的索引来加速选择。你有*** ***和***有效***指数? – 2012-03-01 08:14:29

回答

1

如果你得到PHP Fatal error: Maximum execution time of 60 seconds exceeded那么肯定一些块运行PHP代码的运行语句set_time_limit(60)地方。 PHP CLI模式可能默认为没有时间限制,但是如果任何代码路径设置了时间限制,它将被授予。 PHP运行了近半个小时的原因是因为set_time_limit设置了CPU时间的限制,并且如果进程I/O受限或正在等待其他进程,则总计CPU使用率将在实时时钟后多达60秒。

尝试在set_time_limit中搜索所有源代码。如果您没有找到任何内容,请在脚本的开始处添加set_time_limit(0)以确保60秒限制不来自本地修改的配置文件。例如,在Ubuntu LTS上,PHP CLI配置在/etc/php5/cli/php.ini中定义。

+0

THANKS。对'set_time_limit'有用的信息。grepping显示了这个问题。 – Tom 2013-02-02 10:12:52

2

好了,你可以设置时间限制更大的价值,或者您可以使用set-time-limit()设置无限:

<?php set_time_limit(0); ?> 

但acctually我也用这个在脚本的开始

ignore_user_abort(1); 
1

不幸的是我不能写评论,所以我的问题在这里,如果你手动运行这个会发生什么?它会超时吗?

如果手动运行时没有超时,我会建议您调用一个小小的shell脚本,它实际运行一个shell并在其中运行“/ usr/bin/php /path/file.php”贝壳。

00 00 * * * /usr/local/scripts/start_php_job.sh

File: /usr/local/scripts/start_php_job.sh 
#!/usr/bin/bash 
date 

/usr/local/bin/php /path/to/script 

date 
+0

谢谢。我试着从命令行手动运行它,并得到与通过cron自动触发时相同的错误。 – Tom 2012-03-01 08:39:38

+1

您可以在运行过程中记录内存消耗吗?什么是你的“资源限制(ulimit -a)?我会假设它只是像这样停下来,缓冲区缓存满了用户最大内存使用量,sql-server最大内存使用率或者系统内存使用率达到最大值。我建议你做一个ps -uef(我认为这是一个显示内存的程序),并且grep你的进程,每5秒钟做一次这样做,什么* return *代码实际上也是很好的。在上面描述的shell脚本中,你可以通过echo $?得到错误代码,并且它会显示出来,或许这会给你更多提示。 – 2012-03-01 13:03:36