使用linux ps命令检查脚本的运行实例数

时间:2014-02-04 16:14:13

标签: php shell cron

我有一个cron工作需要大约5分钟才能完成,而且每分钟都会运行一次。 我知道脚本会因为终止而更快地执行,但这是故意的。 我希望同时运行此脚本的大约5个实例,但就像现在一样,服务器将运行太多实例,直到所有内容都冻结。

这就是为什么我想在每个cron的开头执行检查已经运行了多少个实例,并且如果已经有超过5个实例,则立即终止。

我怎样才能最有效地做到这一点?

在线我发现这个片段可能是一个很好的解决方案:

exec("ps auxwww|grep cleaner.php|grep -v grep", $output);
print_r($output);

虽然cleaner.php是相关脚本。

如果我执行此脚本,我会得到以下输出:

    Array
(
    [0] => root      4565  0.0  0.0   6184   776 ?        SNs  15:42   0:00 jailshell (user1) [4732] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [1] => user1  4732  0.0  0.0   6184   396 ?        SN   15:42   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [2] => user1  4733  0.0  0.0 106056  1264 ?        SN   15:42   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [3] => user1  4734  0.0  0.3 366452 15988 ?        SN   15:42   0:00 php /home/user1/public_html/crons/cleaner.php
    [4] => root      4776  0.0  0.0   6184   776 ?        SNs  15:44   0:00 jailshell (user1) [4793] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [5] => user1  4793  0.0  0.0   6184   396 ?        SN   15:44   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [6] => user1  4794  0.0  0.0 106056  1264 ?        SN   15:44   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [7] => user1  4795  0.0  0.3 366452 16008 ?        SN   15:44   0:00 php /home/user1/public_html/crons/cleaner.php
    [8] => root      6111  0.0  0.0   6184   776 ?        SNs  15:46   0:00 jailshell (user1) [6126] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [9] => user1  6126  0.0  0.0   6184   396 ?        SN   15:46   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [10] => user1  6127  0.0  0.0 106056  1264 ?        SN   15:46   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [11] => user1  6128  0.0  0.3 366452 15920 ?        SN   15:46   0:00 php /home/user1/public_html/crons/cleaner.php
    [12] => root      6218  0.0  0.0   6184   776 ?        SNs  15:48   0:00 jailshell (user1) [7368] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [13] => user1  7368  0.0  0.0   6184   396 ?        SN   15:48   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [14] => user1  7369  0.0  0.0 106056  1260 ?        SN   15:48   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [15] => user1  7370  0.0  0.3 366452 15960 ?        SN   15:48   0:00 php /home/user1/public_html/crons/cleaner.php
    [16] => root      7462  0.0  0.0   6184   776 ?        SNs  15:50   0:00 jailshell (user1) [7704] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [17] => user1  7704  0.0  0.0   6184   396 ?        SN   15:50   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [18] => user1  7705  0.0  0.0 106056  1256 ?        SN   15:50   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [19] => user1  7706  0.0  0.3 366452 15960 ?        SN   15:50   0:00 php /home/user1/public_html/crons/cleaner.php
    [20] => root     11969  0.0  0.0   6184   772 ?        SNs  15:52   0:00 jailshell (user1) [11987] ll -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [21] => user1 11987  0.0  0.0   6184   392 ?        SN   15:52   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [22] => user1 11992  0.0  0.0 106056  1264 ?        SN   15:52   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [23] => user1 11993  0.2  0.3 366452 15888 ?        SN   15:52   0:00 php /home/user1/public_html/crons/cleaner.php
    [24] => root     24158  0.0  0.0   6184   780 ?        SNs  15:30   0:00 jailshell (user1) [24232] ll -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [25] => user1 24232  0.0  0.0   6184   400 ?        SN   15:30   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [26] => user1 24254  0.0  0.0 106056  1264 ?        SN   15:30   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [27] => user1 24260  0.0  0.3 366448 15952 ?        SN   15:30   0:00 php /home/user1/public_html/crons/cleaner.php
    [28] => root     28649  0.0  0.0   6184   772 ?        SNs  15:32   0:00 jailshell (user1) [29645] ll -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [29] => user1 29645  0.0  0.0   6184   392 ?        SN   15:32   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [30] => user1 29647  0.0  0.0 106056  1264 ?        SN   15:32   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [31] => user1 29648  0.0  0.3 366452 15972 ?        SN   15:32   0:00 php /home/user1/public_html/crons/cleaner.php
    [32] => root     29821  0.0  0.0   6184   776 ?        SNs  15:34   0:00 jailshell (user1) [29840] ll -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [33] => user1 29840  0.0  0.0   6184   396 ?        SN   15:34   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [34] => user1 29843  0.0  0.0 106056  1260 ?        SN   15:34   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [35] => user1 29845  0.0  0.3 366452 15984 ?        SN   15:34   0:00 php /home/user1/public_html/crons/cleaner.php
    [36] => root     30055  0.0  0.0   6184   776 ?        SNs  15:36   0:00 jailshell (user1) [30090] ll -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [37] => user1 30090  0.0  0.0   6184   396 ?        SN   15:36   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [38] => user1 30101  0.0  0.0 106056  1260 ?        SN   15:36   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [39] => user1 30108  0.0  0.3 366452 15968 ?        SN   15:36   0:00 php /home/user1/public_html/crons/cleaner.php
    [40] => root     31311  0.0  0.0   6184   776 ?        SNs  15:38   0:00 jailshell (user1) [31332] ll -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [41] => user1 31332  0.0  0.0   6184   396 ?        SN   15:38   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [42] => user1 31333  0.0  0.0 106056  1260 ?        SN   15:38   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [43] => user1 31336  0.0  0.3 366452 15976 ?        SN   15:38   0:00 php /home/user1/public_html/crons/cleaner.php
    [44] => root     31610  0.0  0.0   6184   776 ?        SNs  15:40   0:00 jailshell (user1) [31675] ll -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [45] => user1 31675  0.0  0.0   6184   396 ?        SN   15:40   0:00 jailshell (user1) [init] ell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [46] => user1 31680  0.0  0.0 106056  1260 ?        SN   15:40   0:00 /usr/local/cpanel/bin/jailshell -c php /home/user1/public_html/crons/cleaner.php >/dev/null 2>&1
    [47] => user1 31685  0.0  0.3 366452 15972 ?        SN   15:40   0:00 php /home/user1/public_html/crons/cleaner.php
)

现在我有点困惑的是,有些实例是在user1下运行的,有些是在root下运行的,也是关于jailshell的。

上面输出的哪一行意味着脚本当前执行了一次,或者脚本当前是否真正执行了48次?我想更需要过滤。

这是我尝试实现的最佳解决方案吗?

2 个答案:

答案 0 :(得分:1)

我没有使用cpanel / jailshell的经验并使用它来运行cronjobs,但我试图尽我所能地回答这个问题。

从您列出的输出中出现一种模式,即进程的开始时间显然是4组,这使我认为每组4是一个清洁运行的实例。父进程可能正在分支子进程。您可以使用“ps -ef”命令来验证此理论,从而获得父进程。

如果这个理论是正确的,那么你可以使用

exec("ps auxwww | grep cleaner.php | grep -v grep | grep -v jailshell”, $output);

将返回

php /home/user1/public_html/crons/cleaner.php

如果您使用$ ouput上的计数,那么它应该为您提供实际运行的进程数。

在实现方面,您可以使用数据库中的表来存储当前运行的清理程序数量的值,并在crons停止和启动时递增和递减该值。您还需要使用某种形式的事务来执行此操作,因此对表的更新是原子的。

然而,cron每分钟运行一次并持续5分钟这一事实让我觉得您需要考虑使cleaner.php更有效率,这样您就不需要运行5个实例。这意味着您可以解决只有5个清洁器实例同时运行的问题。

通过我对你原来的问题的评论,似乎cpanel / jailshell可能有重复的crons,因为你得到了两个结果

crontab -u root -l和crontab -u user1 -l <​​/ p>

所以我要确保你的cron首先只执行一次而不是root和user1用户。

答案 1 :(得分:0)

简短回答:

在“调整设置”下的WHM中 - &gt; “系统”,标题为“Jailed / proc mount方法”的选项。如果将其设置为“Always mount full / proc”,这将允许CRON启动的脚本通过ps和top查看所有进程。如果你启用了jailshell,你仍然必须忽略它们(即grep -v jailshell),但计数将再次准确。

解释和历史:

这个问题一直困扰着我多年!我在我的几个站点上有很多脚本,CRON每分钟运行一次,但脚本会计算实例,只保留一个自身运行的副本。其中一些计算并允许特定数量的实例。

然而,几年前,所有这些都在2013年的某个时间段cPanel更新后停止了工作。我当时不知道发生了什么但是我注意到我的脚本现在有多个实例,正在运行在“jailshell”PID下。所以,我修改了我的脚本来计算它们。没工作。我改为忽略了jailshell副本“grep -v jailshell”,但这并没有完全发挥作用。我的脚本永远不会运行。他们会说实例太多了。因此,我增加了计数以补偿并使它们运行,但随着时间的推移,多个副本将产生远远超出我施加的限制。几天之内,就会有数百个实例,服务器会停止运行。

今晚,我终于找到了解决方案。

我找到了这个cPanel线程:https://forums.cpanel.net/threads/jailshell-users-not-seeing-processes-in-ps-or-top.351271/

这听起来像是我的问题。 cPanel说这不是问题,因为他们无法从命令行重现它,但他们没有从CRON创建的shell进行测试。那就是问题所在。当CRON运行时,它只能看到在ITS shell中启动的进程;并非该用户的所有流程。

所以,更多的挖掘,我发现提到cPanel使jailshell也mount / proc具有有限的功能。但是,他们在某一点上添加了一个覆盖。它可以在“调整设置”下的WHM中找到 - &gt; “系统”,标题为:“Jailed / proc mount方法”。如果将其设置为“Always mount full / proc”,这将允许CRON启动的脚本通过ps和top查看所有进程。如果你启用了jailshell,你仍然必须忽略它们(即grep -v jailshell),但计数将再次准确。万岁!

我今晚完全测试了这个,我的脚本再次运行,但没有产生失控。

注意:这确实存在安全责任,因为共享主机用户(或此服务器上的受感染站点)可能使用从ps和top派生的信息来逃避jail shell。所以要谨慎使用。我愿意承担风险,因为我保持我的网站更新,编写我自己的代码,并且不能使用服务器。但是,您的情况可能需要更加谨慎。