Laravel调度中的并行任务

时间:2018-11-15 09:45:05

标签: php laravel artisan

我基本上有一个理论上只是一个机器人的系统,我需要在多线程上运行它(是的,我知道它是PHP,所以不可能完全实现),或者可以基于并行运行artisan命令的某个地方运行它雄辩的结果。

当前我的系统如下所示:

这是我的 Kernel.php

protected $commands = [
    Commands\RunBuy::class
] 

protected function schedule(Schedule $schedule)
{
    $schedule->command('buy:cron')->everyMinute();
}

这是我的 RunBuy.php

public function __construct() {
    parent::__construct();
}

public function handle() {
    $this->bot = Bots::where('status', '1')->where('in_use', '0')->first();
    .......
}

我基本上需要相同的功能,但是能够管理多个Bots,具体取决于它们有多少行?我想要做的是这样的:

protected function schedule(Schedule $schedule)
{
    foreach(Bots::where('status', '1')->where('in_use', '0')->get() as $bot) {
        $schedule->command('buy:cron '.$bot->id)->everyMinute();
    }
}

然后在 RunBuy.php 中处理它,如下所示:

protected $signature = 'buy:cron {bot_id : The Bot ID we must perform actions with}';

public function __construct() {
    parent::__construct();
}

public function handle() {
    $bot_id = $this->argument('bot_id');

    $this->bot = Bots::find($bot_id);
    .......
}

但是由于Laravel一个接一个地处理每个命令,这样的事情是行不通的?我需要它们全部同时发射。

1 个答案:

答案 0 :(得分:1)

如果您使用的是Linux系统,则可以直接使用final&调用命令以分叉该过程

$schedule->exec('php artisan buy:cron ' . $bot->id . ' > /dev/null &')->everyMinute();

在Windows上,您可以添加要运行的计划进程(接受1个参数的批处理) 并命名为

$schedule->exec('schtasks /run /tn yourtask.bat ' . $bot->id)->everyMinute();

yourtask.bat应该是一个简单的php artisan调用

cd /path/to/project && php artisan buy:cron %1

或者您可以在后台启动每个进程

function execInBackground($cmd) {
    try {
        if (substr(php_uname(), 0, 7) == "Windows") {
            pclose(popen("start /B " . $cmd, "r"));
        } else {
            exec($cmd . " > /dev/null &");
        }
    } catch (\Exception $ex) {
        throw $ex;
    }
}