PHP如何限制按时任务的历程数量

此刻的事情中,常常要写一些剧本做一些异步的操纵。

一般是大量的数据修改,可能办理部门并发问题。

为了可以或许不变的做好数据处理惩罚,一般环境下会用按时剧本的方法。

那么问题来了。

大概存在的问题

当我们处理惩罚大量数据的时候,剧本的执行时间大概很长,可能反复处理惩罚某条数据(写错的环境下)。

为了制止数据的反复处理惩罚、运行剧本过多导致处事器压力过大等问题,我们需要限制剧本的运行数量。

如何做

思路一

查询某种标识的历程数量,假如高出必然数量,则直接退出,不处理惩罚。

思路二

记录每次的PID,可以利用 文件、redis、memcached 等来存储。

当启动一个新历程的时候,去查一下这个标识下面有哪些PID,是否还在运行,且与当前标识有干系。

当高出必然数量的时候,直接退出,不处理惩罚。

实践

思路一实践

这里通过 linux 的 ps、grep、wc 的呼吁来获取指定标识的运行历程数。

<?php /** * 是否可以运行 * * @param string $ident 标识 * @param integer $maxNum 最大运行数量 * * @return bool */ function canRun($ident, $maxNum) { $cmd = sprintf('ps ax | grep %s | grep -v /bin/sh | grep -v grep | wc -l', $ident); $fp = @popen($cmd, 'r'); $num = (int)trim(@fread($fp, 2096)); @pclose($fp); return $num <= $maxNum; }

思路二实践

这里利用 redis 存储 pid 信息。

通过 /proc/{pid}/cmdline 文件检测指定历程是否还在运行。

<?php /** * 查抄 pid 是否存活 * * @param string $pid PID * @param string $ident 标识 * * @return bool */ function isSurvive($pid, $ident) { // 获取指定pid的cmdline文件 $cmdlinePath = sprintf('/proc/%s/cmdline', $pid); if (!is_file($cmdlinePath)) { return false; } $cmdline = trim(file_get_contents($cmdlinePath)); // 查抄标识是否在 cmdline 中 return strpos($cmdline, $ident) !== false; } /** * 是否可以运行 * * @param string $ident 标识 * @param integer $maxNum 最大运行数量 * * @return bool */ function canRun($ident, $maxNum) { // 假设已经链接上 $redisHandler = getRedis(); // 界说一个key $key = sprintf('php:job:%s:pid', $ident); // 当前的PID $currentPid = getmypid(); // 将当前的PID写入redis $redis->sAdd($key, $currentPid); // 获取redis中的所有pid $pids = $redis->sMembers($key); // 遍历pid,查抄是否有效 foreach ($pids as $index => $pid) { if ($currentPid == $pid) { continue; } // 查抄 pid 是否还在运行中 if (isSurvive($pid, $ident)) { continue; } // 若不再运行,则直接删除 unset($pids[$index]); $redis->sRemove($key, $pid); } return count($pids) <= $maxNum; }

关于标识

关于标识,大概我们在运行一些按时剧本的时候,统一的部门大概就是 php 了;可能,拥有沟通标识的剧本,我们要归为几类。

为了可以或许实现这些需求,我们可以通过 php 的内置函数 cli_set_process_title 来实现自界说 COMMAND。
demo.php:

这个时候,我们运行 demo.php,然后通过 ps ax 可以看到如下功效:

PID USER TIME COMMAND 1 root 0:09 php-fpm: master process (/usr/local/etc/php-fpm.conf) 7 root 0:16 php-fpm: pool www 8 root 0:15 php-fpm: pool www 9 root 0:14 php-fpm: pool www 10 root 0:00 sh 663 root 0:00 sh 690 root 0:00 {php} Job Demo 691 root 0:00 ps ax

修改指定剧本的历程标题,我们就可以实现界说某些剧本的标识了。

最后

没 BUG 的成果,也大概呈现 BUG,我们需要更多的思考和设计淘汰这类错误的产生。

到此这篇关于PHP如何限制按时任务历程数量的文章就先容到这了,更多相关PHP限制历程数量内容请搜索剧本之家以前的文章或继承欣赏下面的相关文章但愿各人今后多多支持剧本之家!

您大概感乐趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsjxzx.html