EasySwoole之定时任务面板

2020-07-20 23:24:15 浏览数 (1)

EasySwoole之定时任务面板


需求

实现物联网设备的数据获取,有些设备的数据需要定时获取

思路

1、做这个功能期间,请教了开发组的成员,最后通过阿正提供的思路来完成

2、首先任务有间隔执行(秒级)和 定时执行(分级),所以就考虑到每种类型的任务开两个进程来执行(也就是正哥所说的管理进程和执行进程),最终间隔执行是开启自定义进程开启一秒的Timer定时器进行从Db查询(定时任务不多的情况下),符合条件的进行投递到Task进程执行并标记为已投递,Task进程根据投递的内容,开启Timer定时器执行相关逻辑(如间隔20秒执行),然后Task进程执行相关逻辑并将定时器Id保存到数据库(用于清除定时器,切记只能清除当前进程的)。定时任务是启动一个Corntab定时任务来查询符合条件的任务,并投递到Task进程执行相关逻辑

界面

间隔执行代码

EasySwooleEvent.php

代码语言:javascript复制
public static function mainServerCreate(EventRegister $register)
    {
        // TODO: Implement mainServerCreate() method.
        //定时任务检测
        $processConfig= new EasySwooleComponentProcessConfig();
        $processConfig->setProcessName('checkTaskProcess');//设置进程名称
        $processConfig->setProcessGroup('Task');//设置进程组
        $processConfig->setEnableCoroutine(true);//是否自动开启协程
        $processConfig->setMaxExitWaitTime(3);//最大退出等待时间
        Manager::getInstance()->addProcess(new CheckTaskProcess($processConfig));
		}

自定义进程代码

代码语言:javascript复制
<?php


namespace AppProcess;


use AppModelAdminCorntabCorntabModel;
use AppTaskTimerTask;
use EasySwooleComponentProcessAbstractProcess;
use EasySwooleComponentTimer;
use EasySwooleEasySwooleTaskTaskManager;

class CheckTaskProcess extends AbstractProcess
{

    protected function run($arg)
    {
        // TODO: Implement run() method.
        //当进程启动后,会执行的回调
        Timer::getInstance()->loop(1*1000,function (){

            $timers = CorntabModel::create()->where('corntab_type',2)->where('corntab_state',0)->all();
            if(!empty($timers)){
                foreach ($timers as $timer)
                {
                    $timer->update(['corntab_state' => 1]);
                    TaskManager::getInstance()->async(new TimerTask($timer->toArray()),null,0);
                }
            }
        });

    }
}

Task进程代码

代码语言:javascript复制
<?php


namespace AppTask;


use AppModelAdminCorntabCorntabModel;
use EasySwooleComponentTimer;
use EasySwooleTaskAbstractInterfaceTaskInterface;

class TimerTask implements TaskInterface
{
    protected $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    function run(int $taskId, int $workerIndex)
    {
        $data = $this->data;
        if(is_array($data))
        {
            $timerId = Timer::getInstance()->loop($data['corntab_intval']*1000,function () use ($data){
                //相关定时业务逻辑
                var_dump($data['corntab_name'].' Task---'.date('Y-m-d H:i:s'));
            });
            $corntab = CorntabModel::create()->get($data['corntab_id']);
            $corntab->update(['corntab_timer_id' => $timerId]);
        }else{
            //清除定时器
            Timer::getInstance()->clear($this->data);
        }



        // TODO: Implement run() method.
    }

    function onException(Throwable $throwable, int $taskId, int $workerIndex)
    {
        // TODO: Implement onException() method.
    }
}

定时执行代码

EasySwooleEvent.php

代码语言:javascript复制
public static function mainServerCreate(EventRegister $register)
    {
	//================================== Ctontab 定时任务 ==============================
        Crontab::getInstance()->addTask(Min::class);
	}

Corntab定时任务代码

代码语言:javascript复制
<?php


namespace AppCrontab;


use AppModelAdminCorntabCorntabModel;
use AppTaskCorntabTask;
use EasySwooleEasySwooleCrontabAbstractCronTask;
use EasySwooleEasySwooleTaskTaskManager;

class Min extends AbstractCronTask
{

    public static function getRule(): string
    {
        // TODO: Implement getRule() method.
        //一分钟执行一次
        return '*/1 * * * *';
    }

    public static function getTaskName(): string
    {
        // TODO: Implement getTaskName() method.
        return 'CrontabOne';
    }

    function run(int $taskId, int $workerIndex)
    {
        $corntabs = CorntabModel::create()->where('corntab_type',1)->where('corntab_state',1)->all();
        if(!empty($corntabs)){
            foreach ($corntabs as $corntab){
                TaskManager::getInstance()->async(new CorntabTask($corntab->toArray()),null,1);
            }
        }
        // TODO: Implement run() method.
    }

    function onException(Throwable $throwable, int $taskId, int $workerIndex)
    {
        // TODO: Implement onException() method.
    }
}

Task进程代码

代码语言:javascript复制
<?php


namespace AppTask;


use AppUtilityLogs;
use EasySwooleTaskAbstractInterfaceTaskInterface;

class CorntabTask implements TaskInterface
{
    protected $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    function run(int $taskId, int $workerIndex)
    {

        $data = $this->data;
        $weeks = explode(',',$data['corntab_day']);
        $day = date('w');
        if(in_array($day,$weeks) && (date('H:i:s') == $data['corntab_time']))
        {
            Logs::getInstance()->log($data['corntab_name'].date('Y-m-d H:i:s')."到时间了,我执行了");
        }

        // TODO: Implement run() method.
    }

    function onException(Throwable $throwable, int $taskId, int $workerIndex)
    {
        echo $throwable->getMessage();
        // TODO: Implement onException() method.
    }
}

效果图

注意

  • Timer定时器清除时,只能清除当前进程的定时器,所以投递任务时需要指定投递的Task进程id
  • 此定时器面板只适用于定时任务比较少的系统,如任务比较多,请考虑优化
  • 本代码仅供学习使用,有优化或者更好的方案可以反馈一起学习讨论
  • 上一篇: EasySwoole之链路追踪
  • 下一篇: 没有了

作者 | 北溟有鱼QAQ

0 人点赞