php版任务管理器,一个php写的任务管理器

/**

* @example php task.php xxx.json

* $task_config = [

*     [

*         'root' => "",//root dir

*         'interval' => 1,

*         'cmd' => "sleep 100",

*         'count' => 1,//start task count

*     ],

*     [

*         'interval' => 1,

*         'cmd' => "sleep 120",

*         'count' => 1,

*     ]

* ];

* @desc this is a daemon manager. when we have a task must always exec or interval less than 1min, because crontab min interval is 1min

* so it is not good when we want less than 1min.

* @author liyunfei

*/

class Task

{

public static $daemonize = true;

public static $arr_worker = [];

public static $conf_file = "task_config.json";

/**

* init php env

*/

public static function init()

{

chdir(dirname(__FILE__));//change to file dirname

$php = explode(" ", system("whereis -b php"));

if (!$php[1]) {

echo "php is not found!";

} else {

$path = getenv("PATH");

putenv("PATH=".$path.":".dirname($php[1]));

}

}

/**

* run all task

*/

public static function run()

{

self::init();

self::daemonize();

while (1) {

echo "\n-----------------------start------------------------\n";

//简单的热加载

$task_config = self::parseConfig();

if (!$task_config) {

sleep(1);

continue;

}

//执行任务

foreach ($task_config as $task) {

self::exec($task);

}

//回收任务占用的资源

self::wait();

echo "\n-----------------------stop------------------------\n";

//echo "1\n";

sleep(1);

}

}

/**

* Run as deamon mode.

* copy from workerman

* @throws Exception

*/

public static function daemonize()

{

if(!self::$daemonize){

return 1;

}

umask(0);

$pid = pcntl_fork();

if($pid === -1){

throw new Exception("fork error!");

}else if($pid > 0){

exit(0);

}

if (-1 === posix_setsid()) {

throw new Exception("setsid fail");

}

// Fork again avoid SVR4 system regain the control of terminal.

if($pid === -1){

throw new Exception("fork error!");

}else if($pid > 0){

exit(0);

}

}

/**

* parse config

* @param unknown $conf_file

* @return array|mixed

*/

public static function parseConfig()

{

$conf_file = self::$conf_file;

$task_config = [];

switch (strrchr($conf_file, '.')) {

case '.ini':

$task_config = parse_ini_file($conf_file);

break;

case '.json':

$task_config = json_decode(file_get_contents($conf_file), 1);

break;

case '.xml':

echo "this old type not use!";

break;

default:

echo "error file type!";

break;

}

return $task_config;

}

/**

* exec task

* @param unknown $task_config

*/

public static function exec($task)

{

//没有任务则跳过

if (!isset($task['cmd']) || $task['cmd'] == '') {

return 1;

}

$tk = substr(md5($task['cmd']), 8, 16);

//判断时间间隔

if (isset($task['interval']) && isset(self::$arr_worker[$tk]['time']) && time() - self::$arr_worker[$tk]['time'] < $task['interval']) {

return 1;

}

if (!isset(self::$arr_worker[$tk])) {

self::$arr_worker[$tk] = [];

self::$arr_worker[$tk]['cnt'] = 0;

}

if (self::$arr_worker[$tk]['cnt'] < $task['count']) {

$cnt = $task['count'] - self::$arr_worker[$tk]['cnt'];//计算还需启动的任务数量

} else {//有足够的任务在运行则不再启动任务

return 1;

}

//print_r(self::$arr_worker);

/* 启动任务 */

for ($i = 0; $i < $cnt; $i++) {

$pid = pcntl_fork();

//echo $pid."\n";

if ( $pid == 0) {//error

//检查是否切换目录

if (isset($task['root']) && $task['root']) {

chdir($task['root']);

}

//echo $task['cmd']."\n";

system($task['cmd']);

exit();

} elseif ($pid == -1) {

echo "fork error!";

} else {

self::$arr_worker[$tk]['pid'][$pid] = $pid;

self::$arr_worker[$tk]['cnt'] += 1;

self::$arr_worker[$tk]['time'] = time();

}

}

}

/**

* 回收任务

*/

public static function wait()

{

while ( ($pid = pcntl_wait($status, WNOHANG)) > 0 ) {

foreach (self::$arr_worker as $key => $worker) {

if (isset($worker['pid'][$pid])) {

self::$arr_worker[$key]['cnt'] -= 1;

}

}

}

}

}

//启动task manager

Task::run();

为什么使用PHP管理crontab 一般在定时任务较少的情况下,使用原生的crontab服务一般不会有什么问题,但当定时任务较多时就会产生如下问题: 文本形式的定时任务可读性很差,在没有任何注释的情况下,新人很难在不读源码的情况下了解定时任务的业务逻辑 在分布式的场景中,定时任务会散落到多台机器上,无法统一管理 定时任务的日志不能集中化管理,对定时任务的运行分析及故障排除比较麻烦 基于以上几点原因,我们迫切的需要一个可以集中化管理的、可配置的定时任务管理器 但自己开发一套分布式的定时任务系统何其复杂,所以作者采用crontab服务做辅助,使用php实现对定时任务的配置管理 使用php管理定时任务有哪些优势 定时任务可以不再是以文本方式的形式存在,可以存储在缓冲、数据库中,甚至你可以开发管理功能,在后台对定时任务进行编辑 定时任务的日志是可配置的,你可以按照业务需求,对日志进行差异化配置 使用方式如下: 编一个任务管理器,可参考test/simple.php 将上述脚本添加到crontab中,一分钟执行一次 示例: <?php $crontab_config = [  'test_1' => [  'name' => '服务监控1',  'cmd' => 'php -v',  'output' => '/tmp/test.log',  'time' => '* * * * *'  ],  'single_test' => [  'name' => 'php -i',  'cmd' => 'php -i',  'output' => '/tmp/single_script.log',  'time' => [  '* * * * *',  '* * * * *',  ],  ], ];  $crontab_server = new \Jenner\Zebra\Crontab\Crontab($crontab_config); $crontab_server->start(); 工具短小,但很精悍 在分布式场景中,你可以把定时任务入数据库中进行统一管理,你可以设定哪些定时任务是由哪些机器执行, 然后通过生成文本文件的方式发送到所有机器上,再由这些机器上的phpCrontab读取处理;从而实现分布式场景下的定时任务统一管理。 标签:Zebra
taskPHP taskPHP基于php开发的定时计划任务框架,利用多进程实现任务的分配和运行,利用内存共享实现进程间通信,支持多线程模式需要安装pthreads扩展(可选),支持linux和windows。有较好的伸缩性、扩展性、健壮稳定性而被多家公司使用,同时也希望开源爱好者一起贡献。   框架概况 框架目录结构: taskPHP 根目录 |-- core 框架系统目录 | |-- lib 框架核心文件目录 | | |-- .... 众多的框架核心类库文件 | |-- guide.php 框架引导文件 | |-- distribute_listen.php 任务派发进程入口 | |-- worker_listen.php 任务执行进程入口 |-- docs 开发文档存放目录 |-- logs 日志目录 |-- tasks 用户任务目录 | |-- demo demo任务 | | |-- Lib demo任务的扩展目录 | | |-- demoTask.php demo任务类文件 | | |-- config.php demo任务配置文件 | | ... 更多任务 | |-- config.php 全局配置文件 |-- main.php 框架入口文件 |-- windows_single.cmd windows快速启动文件 框架说明 linux下子进程执行任务,修改脚本无需重启后台服务立即生效,windows下修改任务脚本后需重启后台脚本 但往系统添加执行不受影响。 框架支持多线程模式,需要安装pthreads扩展(可选)。 使用内存共享实现进程通信,堵塞式消息队列,整个框架的运行无需第三方扩展。 任务派发及具体任务执行不在同个进程[distribute_listen.php]和[worker_listen.php],windows和linux下启用入口文件[main.php],windows下可运行[windows_single.cmd]快速启动。 执行时间语法跟crontab类似,且支持秒设置。 添加任务简单,只需继承Task基类,实现任务入口run方法。 环境要求 php本>= 5.5 开启shmop 注意事项 由于任务存在派发时间,所以任务运行的时间可能会有1-2秒的误差。 windows下执行任务在循环里,编任务有问题或调用exit将导致后台脚本停止,linux下无此问题。 建议生产部署在linux下运行多进程模式,因为运行在多线程模式运行一段时间后报错,pthreads has detected that the core\lib\Pthread could not be started, the system lacks the necessary resources or the system-imposed limit would be exceeded in xxx 文档列表 -->数据库类使用教程 支持(Mysql,Mongo,Oracle,Pgsql,Sqlsrv,Sqllite) -->windows下安装php多线程扩展pthreads教程 -->工具类Utils使用说明 -->http请求客户端类Client使用说明 使用说明 时间配置格式说明: * * * * * * * //格式 :秒 分 时 天 月 年 周 10 * * * * * * //表示每一分钟的第10秒运行 /10 * * * * * * //表示每10秒运行 /1 * 15,16 * * * * //表示 每天的15点,16点的每一秒运行 系统命令说明: main.php [start] 启动 可不带参数 main.php close 结束 main.php reload 重新加载任务 main.php delete demo 删除任务 main.php select 查看任务列表 main.php exec demo 运行任务 主要用于任务开发中调试单个任务 全局配置文件规范 标签:taskphp  计划任务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值