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

如何检查php脚本是否仍在运行,php,process,queue,monitoring,Php,Process,Queue,Monitoring,我有一个PHP脚本,可以监听队列。理论上,它永远不会死。有什么东西可以检查它是否还在运行吗?类似于Ruby的上帝(http://god.rubyforge.org/ )PHP的 上帝是语言不可知论者,但如果有一个同样适用于windows的解决方案,那就太好了。简单bash脚本 #!/bin/bash while [true]; do if ! pidof -x script.php; then php script.php & fi done 一

我有一个
PHP
脚本,可以监听队列。理论上,它永远不会死。有什么东西可以检查它是否还在运行吗?类似于Ruby的上帝(http://god.rubyforge.org/ )
PHP的

上帝是语言不可知论者,但如果有一个同样适用于windows的解决方案,那就太好了。

简单bash脚本

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

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


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

不适用于windows,但

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

这里有一个简单的例子,它一直运行PHP脚本,直到手动停止

#!/bin/bash clear date php -f cli-SCRIPT.php echo "wait a little while ..."; sleep 10 exec $0 #!/bin/bash 清楚的 日期 php-f cli-SCRIPT.php 回声“等一会儿……”;睡眠10 执行官$0
“exec$0”将重新启动脚本,而不会创建一个子进程,该子进程将在以后分解(同时占用资源)。这个bash脚本包装了一个邮件发送者,因此如果它退出并暂停片刻,就不会有问题。

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

php daemon.php 2>&1 | mail -s "Daemon stopped" you@example.org
php daemon.php | mail -s "Daemon stopped" you@example.org
编辑:
从技术上讲,这会立即调用mailer,但仅在php脚本结束时完成命令。执行此操作将捕获php脚本的输出并包含在邮件正文中,这对于调试导致脚本停止的原因非常有用。

如果您掌握了脚本,您可以让他每X次设置一个时间值(以db为单位),然后让cron作业检查该值是否为最新值。

Trolskn写道:


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

php daemon.php 2>&1 | mail -s "Daemon stopped" you@example.org
php daemon.php | mail -s "Daemon stopped" you@example.org
每次在daemon.php中打印一行时,这将调用
mail
(这应该永远不会,但仍然是。)

相反,使用双安培和运算符来分隔命令,即

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

我也有同样的问题——想检查脚本是否正在运行。所以我提出了这个,并将其作为cron作业运行。它将正在运行的进程作为一个数组抓取,循环遍历每一行并检查文件名。看起来很好用。将#user#替换为脚本用户

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

在linux中,按如下方式运行ps:

ps -C php -f
然后,您可以在php脚本中执行以下操作:

$output = shell_exec('ps -C php -f');
if (strpos($output, "php my_script.php")===false) { 
  shell_exec('php my_script.php  > /dev/null 2>&1 &');
}

上面的代码列出了所有完整运行的php进程,然后检查“my_script.php”是否在运行进程列表中,如果没有,它将运行进程,并且不会等待进程终止以继续执行它正在执行的操作。

您可以在crontab中编写如下内容:

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

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

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

// your code here
您的test.php文件应如下所示:

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

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

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

// your code here

灵感来源于贾斯汀·莱文尼的答案,并对其进行了改进,因为
ps-C
在Mac电脑中不起作用,这正是我需要的。因此,您可以在php脚本中使用它(可能就在您需要daemon alive之前),在Mac OS X 10.11.4和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的第一个字母使用正则表达式使得我们的命令与我们搜索的模式不同

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

用于测试php.sh的包装器

#!/bin/bash
php test.php

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

我使用了用于windows的cmder,基于此脚本,我提出了这个脚本,我后来成功地在linux上部署了它

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

以下是我为解决类似问题所做的工作。如果其他人有一个参数化的php脚本,您希望cron频繁执行,但在任何时候只希望运行一次,那么这将有所帮助。将其添加到php脚本的顶部,或者创建一个公共方法

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

另外,注意你的CPU使用率飙升:)不太广泛。。。我经常使用它(好吧,好吧,在cron作业中,每分钟都使用一次),它有太多的错误,我简直不敢相信。[true]是无效的语法,您可以通过等待php脚本结束来消除if。这与我当前使用的God脚本非常相似,肯定比busy-waiting要好。不,在php运行期间,会运行mail命令。但是,一旦它停止,它会发送一个EOF,这会导致邮件发送者发送邮件。你只使用一个&在这里,你的评论是不真实的。邮件不是每行都发送,它只发送EOF。请解释一下选项好吗?