Laravel 调度:每秒执行一个命令

问题描述 投票:0回答:6

我有一个项目需要通过WebSockets不断发送通知。它应该连接到以字符串格式返回总体状态的设备。系统对其进行处理,然后根据各种条件发送通知。

由于调度程序最早可以一分钟重复一个任务,所以我需要找到一种每秒执行该函数的方法。

这是我的

app/Console/Kernel.php

<?php    
  ...    
class Kernel extends ConsoleKernel
{
    ...
    protected function schedule(Schedule $schedule)
    {
        $schedule->call(function(){
            // connect to the device and process its response
        })->everyMinute();
    }
}

PS:如果您有更好的想法来处理这种情况,请分享您的想法。

php laravel cron
6个回答
8
投票

通常,当你想要超过 1 分钟的粒度时,你必须编写一个守护进程。

我建议你尝试一下,现在不像几年前那么难了。只需从 CLI 命令中的一个简单循环开始:

while (true) {
    doPeriodicStuff();

    sleep(1);
}

一件重要的事情:通过 supervisord 运行守护进程。您可以查看有关 Laravel 队列侦听器设置的文章,它使用相同的方法(守护进程+supervisord)。配置部分可以如下所示:

[program:your_daemon]
command=php artisan your:command --env=your_environment
directory=/path/to/laravel
stdout_logfile=/path/to/laravel/app/storage/logs/your_command.log
redirect_stderr=true
autostart=true
autorestart=true

2
投票

每秒您可以将命令添加到 cron 作业

*   *   *   *   *   /usr/local/php56/bin/php56 /home/hamshahr/domains/hamshahrapp.com/project/artisan taxis:beFreeTaxis 1>> /dev/null 2>&1

并指挥:

<?php

namespace App\Console\Commands;

use App\Contracts\Repositories\TaxiRepository;
use App\Contracts\Repositories\TravelRepository;
use App\Contracts\Repositories\TravelsRequestsDriversRepository;
use Carbon\Carbon;
use Illuminate\Console\Command;

class beFreeRequest extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'taxis:beFreeRequest';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'change is active to 0 after 1 min if yet is 1';

    /**
     * @var TravelsRequestsDriversRepository
     */
    private $travelsRequestsDriversRepository;

    /**
     * Create a new command instance.
     * @param TravelsRequestsDriversRepository $travelsRequestsDriversRepository
     */
    public function __construct(
        TravelsRequestsDriversRepository $travelsRequestsDriversRepository
    )
    {
        parent::__construct();
        $this->travelsRequestsDriversRepository = $travelsRequestsDriversRepository;
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $count = 0;
        while ($count < 59) {
            $startTime =  Carbon::now();

            $this->travelsRequestsDriversRepository->beFreeRequestAfterTime();

            $endTime = Carbon::now();
            $totalDuration = $endTime->diffInSeconds($startTime);
            if($totalDuration > 0) {
                $count +=  $totalDuration;
            }
            else {
                $count++;
            }
            sleep(1);
        }

    }
}

1
投票
$schedule->call(function(){
    while (some-condition) {
        runProcess();
    }
})->name("someName")->withoutOverlapping();

根据您的

runProcess()
执行所需的时间,您可以使用
sleep(seconds)
进行更多微调。

some-condition
通常是一个标志,您可以随时更改它以控制无限循环。例如您可以随时使用
file_exists(path-to-flag-file)
手动启动或停止该过程。


0
投票

这可能是一个有点老的问题,但我建议你看一下

laravel-short-schedule 来自 spatie 的包

它允许您在亚分钟甚至亚秒内运行命令


0
投票

我通过在方法

app/Console/Kernel.php
中使用我的
schedule()
解决了这个问题:

        if (!\Illuminate\Support\Facades\Cache::get('myProcessHeartbeat')) {
            $schedule->call(
                function () {
                    while (true) {
                        \Illuminate\Support\Facades\Cache::put(
                            'myProcessHeartbeat',
                            'pulse',
                            30
                        );
                         \Illuminate\Support\Facades\Artisan::call(
                            'YOUR-COMMAND-HERE'
                        );
                        sleep(15);
                    }
                }
            );
        }

我第一次尝试@Inno解决方案,但如果脚本提前退出,Laravel将等待

24
小时自动删除锁Laravel任务调度 - 防止任务重叠这对我的应用程序来说是致命的。

我的解决方案最多会空闲

1
分钟,并且一次仅运行进程,因为 Laravel 调度运行器被执行为在服务器上每分钟运行一次。


-3
投票

您可以尝试使用 sleep(1) 每秒复制作业 * 60 次。

© www.soinside.com 2019 - 2024. All rights reserved.