run_status = true; } $this->cron_lists = DevCrontab::where(['status' => 1])->select()->toArray(); if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $this->system = 1; } else { $this->system = 2; } } /** * 运行定时任务 * @return string * @throws Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException * @throws \think\exception\PDOException */ public function execute() { if (empty($this->cron_lists)) { return '当前无需要执行的定时任务或守护进程'; } DevCrontab::where(['status' => 1])->update(['error' => '']); if ($this->system == 1) { self::windows($this->cron_lists); } else { self::unix($this->cron_lists); } } /** * unix系统 * @param $cron_lists */ private function unix($cron_lists) { $task = new Worker(); $task->count = count($cron_lists);//根据列表任务分配线程 $task->onWorkerStart = function ($task) use ($cron_lists) { $task_id = $task->id; //创建定时器 $timer_id = Timer::add(1, function () use (&$timer_id, $task_id, $cron_lists) { try { self::setStatus(); Db::close(); $time = time(); $cron = $cron_lists[$task_id]; if ($cron['type'] == 1) { if (CronExpression::isValidExpression($cron['expression']) === false) { throw new \Exception("规则设置错误"); //定时任务运行规则错误,不执行 } $cron_expression = CronExpression::factory($cron['expression']); $last_time = Db::name('dev_crontab')->where(['id' => $cron['id']])->value('last_time'); $next_time = $cron_expression->getNextRunDate(date('Y-m-d H:i:s', $last_time))->getTimestamp(); if ($next_time >= time()) { sleep(1); return true; } } //执行定时任务 Debug::remark('begin'); $parameter = explode(' ', $cron['parameter']); if (is_array($parameter) && !empty($parameter)) { Console::call($cron['command'], $parameter); } else { Console::call($cron['command']); } Debug::remark('end'); echo "系统任务名称为:{$cron['name']}:" . "\n"; } catch (\Exception $e) { //运行错误,关闭定时任务 echo "系统任务名称为:{$cron['name']}:" . $e->getMessage(); Db::name('dev_crontab') ->where(['id' => $cron['id']]) ->update(['error' => $e->getMessage(), 'status' => 3]); Timer::del($timer_id); } catch (Exception $e) { echo "系统任务名称为:{$cron['name']}:" . $e->getMessage(); Db::name('dev_crontab') ->where(['id' => $cron['id']]) ->update(['error' => $e->getMessage(), 'status' => 3]); Timer::del($timer_id); } $range_time = Debug::getRangeTime('begin', 'end'); $max_time = max($cron['max_time'], $range_time); Db::name('dev_crontab') ->where(['id' => $cron['id']]) ->update(['last_time' => $time, 'time' => $range_time, 'max_time' => $max_time]); }); }; Worker::runAll(); } /** * windows系统下 * @param $cron_lists */ private function windows($cron_lists) { $task = new Worker(); $task->count = 1; $task->onWorkerStart = function ($task) use ($cron_lists) { //创建定时器 $timer_id = Timer::add(1, function () use ($cron_lists) { self::setStatus(); foreach ($cron_lists as $k => $v) { $cron = $v; try { $time = time(); if ($cron['type'] == 1) { if (CronExpression::isValidExpression($cron['expression']) === false) { throw new \Exception("规则设置错误"); //定时任务运行规则错误,不执行 } $cron_expression = CronExpression::factory($cron['expression']); $last_time = Db::name('dev_crontab')->where(['id' => $cron['id']])->value('last_time'); $next_time = $cron_expression->getNextRunDate(date('Y-m-d H:i:s', $last_time))->getTimestamp(); if ($next_time >= time()) { usleep(100000); continue; } } //执行定时任务 Debug::remark('begin'); $parameter = explode(' ', $cron['parameter']); if (is_array($parameter) && !empty($parameter)) { Console::call($cron['command'], $parameter); } else { Console::call($cron['command']); } Debug::remark('end'); echo "系统任务名称为:{$cron['name']}:" . "\n"; } catch (\Exception $e) { //运行错误,关闭定时任务 echo "系统任务名称为:{$cron['name']}:" . $e->getMessage(); Db::name('dev_crontab') ->where(['id' => $cron['id']]) ->update(['error' => $e->getMessage(), 'status' => 3]); } catch (Exception $e) { echo "系统任务名称为:{$cron['name']}:" . $e->getMessage(); Db::name('dev_crontab') ->where(['id' => $cron['id']]) ->update(['error' => $e->getMessage(), 'status' => 3]); } $range_time = Debug::getRangeTime('begin', 'end'); $max_time = max($cron['max_time'], $range_time); Db::name('dev_crontab') ->where(['id' => $cron['id']]) ->update(['last_time' => $time, 'time' => $range_time, 'max_time' => $max_time]); } }); }; Worker::runAll(); } /** * 设置状态 * @return mixed */ private function setStatus() { return Cache::set('crontab_run_status', 1, 60); } /** * 更新定时任务状态 * @throws Exception * @throws \think\exception\PDOException */ public function updateStatus() { if ($this->run_status === false) { $this->cron_lists = Db::name('dev_crontab') ->where(['status' => 1]) ->update(['status' => 2]); } } /** * 启动 * @param bool $stop */ public function run($stop = true) { $php_path = real_path(); $this->setStatus(); if ($stop) { if ($this->system == 1) { pclose(popen("start taskkill /f /im php.exe /t", 'r')); } else { pclose(popen($php_path . ' ../think crontab stop --d', 'r')); } } else { if ($this->system == 1) { pclose(popen("start taskkill /f /im php.exe /t", 'r')); sleep(2); pclose(popen("start " . $php_path . " ../think crontab restart --d", 'r')); } else { pclose(popen($php_path . ' ../think crontab restart --d', 'r')); } } } }