PHP如何限制定时任务的进程数量
发布:smiling 来源: PHP粉丝网 添加日期:2022-04-19 08:52:33 浏览: 评论:0
这篇文章主要给大家介绍了关于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,我们需要更多的思考和设计减少这类错误的发生。
Tags: PHP限制定时任务
- 上一篇:PHP中的变量覆盖漏洞深入解析
- 下一篇:最后一页
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)