我试图在不同的时间在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
。
因此,请确保exit
或die()
中没有任何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作业上