导航

TP6:Worerman定时任务的后台守护执行

Posted on 2022-05-10 13:48  eastson  阅读(965)  评论(0编辑  收藏  举报

使用Timer创建定时的任务,可以以后台守护进程的方式执行。

Worker::runAll()执行时,会执行其中的parseCommand()方法。

protected static function parseCommand()
{
    // 守护进程执行方式,只会在LINUX系统下才可以
    if (static::$_OS !== \OS_TYPE_LINUX) {
        return;
    }
    
    // 命令和参数是通过$argv传递给Workerman的。
    
    global $argv;
    
    // Check argv;
    $start_file = $argv[0];
    $available_commands = array(
        'start',
        'stop',
        'restart',
        'reload',
        'status',
        'connections',
    );
    
    //
    // 通常的执行命令格式:
    //     php timer.php start
    //       php timer.php start -d
    // 对应的$argv[0]=timer.php,$argv[1]=start
    //
    
    $usage = "Usage: php yourfile <command> [mode]\nCommands: \nstart\t\tStart worker in DEBUG mode.\n\t\tUse mode -d to start in DAEMON mode.\nstop\t\tStop worker.\n\t\tUse mode -g to stop gracefully.\nrestart\t\tRestart workers.\n\t\tUse mode -d to start in DAEMON mode.\n\t\tUse mode -g to stop gracefully.\nreload\t\tReload codes.\n\t\tUse mode -g to reload gracefully.\nstatus\t\tGet worker status.\n\t\tUse mode -d to show live status.\nconnections\tGet worker connections.\n";
    if (!isset($argv[1]) || !\in_array($argv[1], $available_commands)) {
        if (isset($argv[1])) {
            static::safeEcho('Unknown command: ' . $argv[1] . "\n");
        }
        exit($usage);
    }

    // Get command.
    $command  = \trim($argv[1]);
    $command2 = isset($argv[2]) ? $argv[2] : '';

    // Start command.
    $mode = '';
    if ($command === 'start') {
        if ($command2 === '-d' || static::$daemonize) {
            $mode = 'in DAEMON mode';
        } else {
            $mode = 'in DEBUG mode';
        }
    }
    
    ... ...
}

所以,Workerman建议的使用方法是,创建单独的执行文件。

<?php
require_once 'vendor/workerman/workerman/Autoloader.php';

use Workerman\Worker;
use Workerman\Lib\Timer;

$worker = new Worker();

$worker->onWorkerStart = function()
{
    // 每隔3秒钟执行一次
    Timer::add(3, function() {
        echo 'Hello ' . date('Y-m-d H:i:s') . PHP_EOL;
    });
};

Worker::runAll();

如何与Thinkphp的命令模式集成在一起使用的?那就需要在Command文件中按照Workman的要求,重置$argv参数数组。
参考手把手教你在tp6中实现毫秒级定时任务功能

protected function initialize(Input $input, Output $output)
{
	global $argv;
	
	if ($input->hasOption('i'))
		$this->interval = floatval($input->getOption('i'));
		
	$argv[1] = $input->getArgument('status') ?: 'start';
	
	if ($input->hasOption('d')) {
		$argv[2] = '-d';
	} else {
		unset($argv[2]);
	}
}