在Laravel安排多个cron


Schedule multiple crons in Laravel

我试图在不同的时间在Laravel中运行多个作业。这是代码:

protected function schedule(Schedule $schedule)
{
    $schedule->command('emails:send')->dailyAt('08:00');
    $schedule->command('emails:evening-status')->dailyAt('17:00');
    $schedule->command('email:weekly-report')->weekly()->mondays()->at('08:00');
}

这里的问题是只有第一个命令emails:send起作用。其他命令在指定时间不起作用。然而,当我手动运行它们时,它们工作得很好。

我缺少的是什么?

我认为您可能需要查看实际的服务器cron配置。Laravel调度程序要求每分钟运行一次服务器cron,以便所有调度都能在所需时间运行。你可能只是让cron在每天早上8点运行,而不是每分钟运行一次。

这可能值得一试,我知道我刚开始安排的时候遇到了同样的问题。

使用调度程序时,您只需要将以下Cron条目添加到服务器中。如果你不知道如何将Cron条目添加到服务器中,可以考虑使用Laravel Forge这样的服务,它可以为你管理Cron条目:

* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1

这个Cron每分钟都会调用Laravel命令调度程序。当schedule:run命令执行时,Laravel将评估您的计划任务并运行到期任务。

类似的情况,只是我使用call为每个cron调用一个方法,例如:

$schedule->call(''App'Http'Controllers'comm'commCron::abc');
$schedule->call(''App'Http'Controllers'comm'commCron::xyz');

我也遇到了同样的问题,后来意识到第一个cron在某个错误点调用了exit

因此,请确保exitdie()中没有任何crons转发。只需return false(如果需要的话(。

添加这个问题已经4年了,但我希望我的答案仍然能帮助任何人。在我的案例中(根据您的案例改编(,我只是在我的Kernel.php中添加了一些带有Laravel的Carbon包的条件案例。

在我的情况下,我想运行3个调度器。两个调度器将在每周一上午8点和下午5点运行一次,另一个调度器将每天运行一次。这就是我提出条件的方式。

public function schedule(Schedule $schedule)
{
   if(Carbon::now()->format('N') == '1')  //check if today is Monday
   {
      if(Carbon::now()->format('G') == '8')  //check if now is 8 AM
      {
         $schedule->command('first:command')->everyMinute();
      }
      if(Carbon::now()->format('G') == '17') //check if now is 5 PM
      {
         $schedule->command('second:command')->everyMinute();
      }
   }
   $schedule->command('another:command')->dailyAt('08:00')->withoutOverlapping();
}

然后,您可以将服务器中的cron作业设置为每小时运行一次。another:command计划不会每天运行24次,因为我添加了withoutOverlapping()方法,它只会在上午8点运行。如有必要,请参阅关于日程安排的laravel文档和关于日期-时间格式的PHP文档。

如果第二个命令不起作用:

$schedule->command('emails:evening-status')
             ->dailyAt('17:00');

您可以在一些文件中只插入一行打印当前日期的代码,例如"test.txt",然后在创建文件时检查所需的时间。若创建了文件,那个么您可以得出这样的结论:计划的脚本中的代码有问题。

使用队列处理作业

在cron上,将所有作业添加到队列

运行多个队列工作程序

您可以尝试以下代码:

protected function schedule(Schedule $schedule)
{
        $schedule->command('emails:send')
                 ->dailyAt('08:00')->withoutOverlapping();
        $schedule->command('emails:evening-status')
                 ->dailyAt('17:00')->withoutOverlapping();
        $schedule->command('email:weekly-report')
                 ->weekly()->mondays()->at('08:00')->withoutOverlapping();
}

上面的代码只是执行而没有重叠。你可以得到更多关于防止重叠的想法。

如果你们还面临同样的问题,请告诉我。

我们在使用Laravel的内置调度模块时遇到了类似的问题。

在我们的案例中,第一个命令以静默方式失败,并阻止了后续调度命令的运行。

作为一个快速测试,请尝试更改命令的顺序,使电子邮件:send位于底部,看看是否有效。一般来说,捕获可能引发的任何异常,它应该会解决问题。

如果您需要使用Laravel Schedule,请使用此代码

    $schedule = new Schedule();
    $schedule->command('emails:send')
             ->dailyAt('08:00')->withoutOverlapping();
    $schedule = new Schedule();
    $schedule->command('emails:evening-status')
             ->dailyAt('17:00')->withoutOverlapping();
    $schedule = new Schedule();
    $schedule->command('email:weekly-report')
             ->weekly()->mondays()->at('08:00')->withoutOverlapping();

但是这种方式可能是错误的,建议使用Laravel artisan命令并将该cammand放在主机cron作业上