Phplayers 2019-06-28
定时器任务,在WEB应用比较常见,如何使用PHP实现定时器任务,大致有两种方案:
1)使用Crontab命令,写一个shell脚本,在脚本中调用PHP文件,然后定期执行该脚本;
2)配合使用ignore_user_abort()和set_time_limit(),使脚本脱离浏览器运行。前者是利用Linux的特性,和PHP本身没有多大关系,后者使用场景有限,且只能由一次HTTP请求触发该脚本,执行完后退出。那么我们如何使用纯PHP实现纯粹的定时器任务,且能适应认识任务业务需求?
基于cli模式运行,依赖php扩展 swoole
因该定时器支持毫秒,时间间隔较小,未来防止进程堆积,做了进程判断,进程存在就本次停止,等待下一次执行。
<?php /** * 基于swoole 毫秒定时器 * */ // 当前的运行环境是否是cli模式 function is_cli() { return preg_match("/cli/i", php_sapi_name()) ? true : false; } /** * 计划任务定时检测master进程是否存在,不存在则启动,以root用户运行 * shell基本命令 *(1)ps aux 显示系统全部进程,一行一个 *(2)grep “abc” 从标准输入读取字符流,输出包含字符串“abc”的行 *(3)grep -v "acb" 从标准输入读取字符流,输出不包含字符串“grep”的行 *(4)wc -l 从标准输入读取字符流,输出行数 * * */ function checkMaster() { $cmd = 'ps axu | grep "consume" | grep -v "grep" | wc -l'; $ret = shell_exec("$cmd"); $ret = rtrim($ret, "\r\n"); echo "查看进程:".$ret."===". $cmd . "\n"; return $ret; } if (is_cli()) { swoole_timer_tick(2000, function () { // 判定进程是否存在 $ret = checkMaster(); if ($ret === "0") { $start_master_cmd = "/usr/bin/php /var/www/html/cctv/Html/index.php /Home/TaskSi/consume.html >> /var/www/html/cctv/Runtime/Logs/huisu_si.log &"; $ret = shell_exec("$start_master_cmd"); // var_dump($ret); echo '开启进程:' . $start_master_cmd . "\n==============================\n"; } else { echo "进程已存在~~休息一下~~(".$ret.")\n==============================\n"; } }); } else { exit("非cli模式,已经停止执行!\n"); }
<?php. if (!empty($_POST)) {. $data1 = $_POST["data1"];$data2 = $_POST["data2"];$fuhao = $_POST["fuh