2012-03-01 106 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