如何检查php脚本是否仍在运行

时间:2008-09-22 20:03:50

标签: php process queue monitoring

我有一个监听队列的PHP脚本。从理论上说,它永远不应该死。有什么东西要检查它是否还在运行?类似于Ruby's God ( http://god.rubyforge.org/ )的{​​{1}}?

上帝是语言无关的,但是有一个适用于Windows的解决方案也会很好。

12 个答案:

答案 0 :(得分:12)

我遇到了同样的问题 - 想要检查脚本是否正在运行。所以我想出了这个,我把它作为一个cron工作。它将正在运行的进程作为一个数组进行抓取,并循环访问每一行并检查文件名。似乎工作正常。将#user#替换为您的脚本用户。

exec("ps -U #user# -u #user# u", $output, $result);
foreach ($output AS $line) if(strpos($line, "test.php")) echo "found";

答案 1 :(得分:4)

在脚本之后添加第二个命令。当/如果它停止,则调用第二个命令。例如:

php daemon.php 2>&1 | mail -s "Daemon stopped" you@example.org

编辑:

从技术上讲,这会立即调用邮件程序,但只在php脚本结束时才完成命令。这样做会捕获php脚本的输出并包含在邮件正文中,这对于调试导致脚本暂停的原因非常有用。

答案 2 :(得分:2)

简单的bash脚本

#!/bin/bash
while [true]; do
    if ! pidof -x script.php;
    then
        php script.php &
    fi
done

答案 3 :(得分:2)

不适用于Windows,但是......

我有一些长期运行的PHP脚本,它们有一个shell脚本包装它。您可以选择从将在shell脚本中检查的脚本中返回一个值,以退出,立即重启,或者休眠几秒钟,然后重新启动。

这是一个简单的操作,只是一直运行PHP脚本,直到它被手动停止。

#!/bin/bash
clear
date
php -f cli-SCRIPT.php
echo "wait a little while ..."; sleep 10
exec $0

“exec $ 0”重新启动脚本,而不创建稍后必须解开的子流程(并在此期间占用资源)。这个bash脚本包装了一个邮件发件人,所以如果它退出并暂停一段时间就没问题了。

答案 4 :(得分:1)

您可以在crontab中写下这样的内容:

0 3 * * * /usr/bin/php -f /home/test/test.php my_special_cron

您的test.php文件应如下所示:

<?php

php_sapi_name() == 'cli' || exit;

if($argv[1]) {
   substr_count(shell_exec('ps -ax'), $argv[1]) < 3 || exit;
}

// your code here

这样,只有一个活动的cron作业实例,my-special-cron作为进程键。因此,您可以在同一个php文件中添加更多作业。

test.php system_send_emails sendEmails

test.php system_create_orders orderExport

答案 5 :(得分:0)

一种可能的解决方案是让它使用套接字函数侦听端口。您可以使用简单的脚本检查套接字是否仍在侦听。即使像pingdom这样的监控服务也可以监控其状态。如果它死了,套接字就不再听了。

很多解决方案..祝你好运。

答案 6 :(得分:0)

如果您亲自操作脚本,可以让他在db中每隔X次设置一个时间值,然后让cron作业检查该值是否是最新的。

答案 7 :(得分:0)

troelskn写道:

  

在脚本之后添加第二个命令。当/如果它停止,则调用第二个命令。例如:

php daemon.php | mail -s "Daemon stopped" you@example.org

每次在daemon.php中打印一行时都会调用mail(这应该是永远的,但仍然是。)

相反,使用双符号运算符来分隔命令,即

php daemon.php & mail -s "Daemon stopped" you@example.org

答案 8 :(得分:0)

受到Justin Levene的回答的启发并改进了它,因为ps -C在Mac中不起作用,在我的情况下我需要它。所以你可以在php脚本中使用它(可能就在你需要守护进程之前),在Mac OS X 10.11.4&amp; Ubuntu 14.04:

$daemonPath = "FULL_PATH_TO_DAEMON";
$runningPhpProcessesOfDaemon = (int) shell_exec("ps aux | grep -c '[p]hp ".$daemonPath."'");
if ($runningPhpProcessesOfDaemon === 0) {
    shell_exec('php ' . $daemonPath . ' > /dev/null 2>&1 &');
}

小但有用的细节:为什么grep -c '[p]hp ...'代替grep -c 'php ...'

因为计数过程grep -c 'php ...'将被视为适合我们模式的过程。所以使用正则表达式为PHP的第一个字母使我们的命令与我们搜索的模式不同。

答案 9 :(得分:0)

如果您在直接检查PHP脚本时遇到问题,可以制作一个简单的包装器并检查它。我对Windows脚本的熟悉程度不足以说明它是如何在这里完成的,但在Bash中,它看起来像......

wrapper_for_test_php.sh

#!/bin/bash
php test.php

然后你只需要检查包装器,就像检查任何其他bash脚本一样:pidof -x wrapper_for_test_php.sh

答案 10 :(得分:0)

我已经使用了cmder for windows,基于这个脚本我想出了一个我以后设法在linux上部署的。

#!/bin/bash
 clear
 date
 while true
 do
    php -f processEmails.php
    echo "wait a little while for 5 secobds..."; 
    sleep 5
 done 

答案 11 :(得分:0)

这是我为解决类似问题所做的工作。如果其他任何人都有您希望cron经常执行但只希望一次执行一次的参数化php脚本,这将很有帮助。将其添加到您的php脚本的顶部,或创建一个通用方法。

$runningScripts = shell_exec('ps -ef |grep '.strtolower($parameter).' |grep '.dirname(__FILE__).' |grep '.basename(__FILE__).' |grep -v grep |wc -l');
if($runningScripts > 1){
    die();
}