我正在使用主管 (http://supervisord.org/) 来守护一个相当标准的 PHP 脚本。该脚本的结构类似于:
while (1) {
// Do a SQL select
// for any matching rows, do something
// if I have been running for longer than 60 mins, exit
}
今天,这个脚本(现在已经相当稳定了一段时间)挂了。它没有崩溃(即发出 SIGHUP 或 SIGTERM 信号),这会提醒 supervisord 重新启动进程。它在处理过程中没有遇到任何错误,这些错误要么被脚本捕获,要么至少触发了 fatal error 并退出。而不是这些“可捕捉的”场景,它只是坐在那里。我们确实有一个 cron 作业设置,每小时运行一次以通过 supervisorctl Hook 重新启动脚本,因为人们普遍认为 PHP 脚本在内存方面存在泄漏,如果运行时间长,最好重新启动。脚本在重启后恢复正常运行。
我的问题:如何检测到该脚本已挂起?如果我没有以某种方式提醒该状态,我什至无法开始诊断或解决它挂起的原因。我正在寻找解决此问题的软件解决方案,或者我可以自己编写解决方案的方法(使用 PHP、Python、perl 或 shell)。
该脚本是用 PHP 5.2.6 编写的,并在最新的 RHEL 5 服务器上运行。
如果我可以分享任何其他信息,如果它有助于提供更出色的解决方案,请告诉我。
谢谢!
Shaheeb R.
最佳答案
由于这是脚本挂起的情况,PHP 可能不会处理任何可以检测到此挂起的附加代码。出于这个原因,我建议修改脚本以保留日志。这将允许主脚本让它之外的任何东西知道它仍在运行,并且通过一些适当的更新,它还可以帮助查明哪里出了问题。
日志记录可以写入文件或数据库,并且至少应包含脚本状态的指示符,例如上次修改日期。如果这个脚本没有持续运行,那么也应该有一些东西表明它正在运行或已经停止。在您给出的示例中,日志写入将在 while 循环中至少发生一次,可能更多。打开指针或数据库连接会花费时间/资源,因此我建议只记录需要的内容。 (注意:如果使用文本文件方法,则需要在每次写入后立即关闭文件。)
例子:
while (1) {
log('Running SQL select');
// Do a SQL select
log('Results retrieved');
// for any matching rows, do something
// (check log) if I have been running for longer than 60 mins, exit
}
function log($msg) {
// Write timestamp, $msg to log
}
一个单独的脚本需要检查日志并报告任何错误,如果它受到导致主脚本挂起的因素的影响,这可能会有问题,但我想不出替代方案。
关于内存,如果您还没有使用 mysql_free_result你应该试一试。
关于php - 如何检测 PHP CLI 脚本处于挂起状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7197926/