我设置了一个虚拟命令作业,其handle()
函数如下:
public function handle()
{
$this->line('==================');
$this->line('Running my job at ' . Carbon::now());
$this->line('Ending my job at ' . Carbon::now());
}
如您所见,它实际上并不做任何事情,只是向标准输出返回几行信息。
现在,在我的App\Console\Kernel
课程中,我设置了以下时间表:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyMinute()
-> appendOutputTo (storage_path().'/logs/laravel_output.log');
}
现在,从命令行运行php artisan schedule:run
。
==================
Running my job at 2018-02-08 11:01:33
Ending my job at 2018-02-08 11:01:33
到目前为止一切顺利。看起来我的计划正在运行。但是,如果我在同一分钟内再次运行该命令,我的日志文件现在显示:
==================
Running my job at 2018-02-08 11:01:33
Ending my job at 2018-02-08 11:01:33
==================
Running my job at 2018-02-08 11:01:51
Ending my job at 2018-02-08 11:01:51
换句话说,日程表的运行频率似乎超过了每分钟,这似乎违反了我在日程表中定义的规则。
更令人困惑的是,我可以将时间表更改为每5分钟运行一次,而不是每分钟运行一次:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyFiveMinutes()
-> appendOutputTo (storage_path().'/logs/laravel_output.log');
}
然后运行php artisan schedule:run
,得到以下输出
没有准备好运行的计划命令。
我可以等你喜欢的时间(即超过5分钟),但我仍然没有输出到我的日志文件。
当我使用Windows任务计划程序来计划我的命令时,我观察到了完全相同的行为(是的,我的开发环境是Windows 7机器,是的,这是Windows中的cron-job)。
问题
那么这是怎么回事呢?artisan schedule:run
命令是如何确定哪些命令正在“等待”执行的呢?我曾想象会有某种日志文件来记录这样一个事实:“命令X在1小时的时间表上运行,最后一次运行是在09:00,所以不要在10:00之前再次执行它”,但我没有找到这样一个日志的痕迹。
有人能给予我点提示吗?
谢谢!
3条答案
按热度按时间zxlwwiss1#
我知道回答你自己的问题不太好。不管怎样,假设这是我的日程安排:
我发现这段代码并没有将作业设置为每5分钟运行一次,也没有阻止在不到5分钟前运行的命令再次运行。
一个更好的思考方法是,这段代码将命名命令 “设置为每当当前时间的分钟数为
0
或5
“ 时可运行。换句话说,如果我运行命令行参数:php artisan schedule:run
在11:04
,则响应为:但如果我在
11:00
或11:05
上运行相同的命令,则会得到:最后在日志文件中得到输出。
当我的
everyFiveMinutes()
计划每10分钟在我的文件中创建一个日志时,我发现了上面的问题,因为我的任务计划程序每2分钟运行一次。wr98u20j2#
我回答这个问题只是为了让其他人知道(因为我也有同样的困惑)。
Laravel调度程序通过检查任务的cronned时间(以分钟为单位)是否与当前时间完全相同来完成与Linux cron完全相同的工作。
当您在crontab中设置
* * * * * ... php artisan schedule:run >> ...
时,您将每分钟运行schedule:run
0秒,如'1:00:00','1:01:00','1:02:00'等。所以,如果你在Laravel调度器中设置命令在“mondays at 1:00”运行(假设),而你是在周一的1:00,它将被执行,不管当前秒数。最后一部分(秒)对于理解它是如何工作的很重要。
例如,你是在周一1:00:05(1:00后5秒),所以cron已经启动了
schedule:run
,你的任务正在执行。然后你打开你的终端,转到你的项目的根目录,手动启动php artisan schedule:run
。那时,可能是1:00:30(1:00后30秒)。好吧,现在你的任务将再次执行,因为1:00:30仍然是1:00的一部分。所以你可以在1:00执行N次schedule:run
,它将执行N次你计划在1:00运行的任务。这就是不需要表格或文件来控制进程启动时间的神奇之处。分钟是cron的最小单位,所以除非你做错了事情(比如复制
schedule:run
行,黑客运行命令more often than a minute等),否则你的Laravel任务将在所需的时间执行一次。只是一个提示:检查你的时区在
config/app.php
中是否正确。我疯狂地理解为什么像everyMinute(), everyFiveMinutes()
这样的东西能工作,而dailyAt('1:10')
不能。当然,Laravel在UTC和我在GMT-3(服务器时钟),我在小时上有很大的差异。eit6fx6z3#
现在回答这个问题已经晚了,但我正在为这个问题的解决方案增加一些价值。
我使用了这个命令
php artisan schedule:work
作为解决方案,这样就不需要每秒钟或每分钟运行一次schedule:run
。我希望这将增加问题的价值。