car*_*rse 9 laravel laravel-5 laravel-artisan
我设置了一个虚拟命令作业,其handle()功能如下:
public function handle()
{
$this->line('==================');
$this->line('Running my job at ' . Carbon::now());
$this->line('Ending my job at ' . Carbon::now());
}
Run Code Online (Sandbox Code Playgroud)
如您所见,它实际上并没有做任何事情,只是将几行信息返回到标准输出。
现在,在我的App\Console\Kernel课堂上,我制定了以下时间表:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyMinute()
-> appendOutputTo (storage_path().'/logs/laravel_output.log');
}
Run Code Online (Sandbox Code Playgroud)
现在,我从命令行运行php artisan schedule:run. 我的laravel_output.log文件中的输出读取
==================
Running my job at 2018-02-08 11:01:33
Ending my job at 2018-02-08 11:01:33
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。看来我的日程正在运行。但是,如果我在同一分钟内再次运行该命令,我的日志文件现在会显示:
==================
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
Run Code Online (Sandbox Code Playgroud)
换句话说,时间表似乎比每分钟都更频繁地运行,这在我看来违反了我在时间表中定义的规则。
更令人困惑的是,我可以将计划更改为每 5 分钟而不是每分钟运行一次:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyFiveMinutes()
-> appendOutputTo (storage_path().'/logs/laravel_output.log');
}
Run Code Online (Sandbox Code Playgroud)
然后运行php artisan schedule:run,然后我得到以下输出
没有准备好运行的预定命令。
我可以等你多久(即超过 5 分钟),但我的日志文件仍然没有输出。
当我使用 Windows 任务计划程序安排我的命令时,我观察到完全相同的行为(是的,我的开发环境是 Windows 7 机器,是的,这是 Windows 等价的 cron 作业)。
发生什么了?artisan schedule:run命令如何确定哪些命令在要执行的计划中“等待”?我曾想象会有某种日志文件来记录这样一个事实:“Command X 是在 1 小时的计划中,最后一次运行是在 09:00,所以不要在 10:00 之前再次执行它”,但是我一直找不到这样的日志的踪迹。
有人可以给我一个线索吗?
谢谢!!
car*_*rse 16
回答你自己的问题并不酷,我知道。无论如何,让我们想象一下这是我的日程安排:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyFiveMinutes()
-> appendOutputTo ('/my/logs/laravel_output.log');
}
Run Code Online (Sandbox Code Playgroud)
我发现此代码不会将您的工作设置为每 5 分钟运行一次。如果命令在不到 5 分钟前运行,它也不会阻止命令再次运行。
更好的思考方式是,这段代码将命名命令设置为“每次当前时间的分钟数为0or时都可运行5”。换句话说,如果我运行命令行参数:php artisan schedule:runat 11:04,那么响应是:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyFiveMinutes()
-> appendOutputTo ('/my/logs/laravel_output.log');
}
Run Code Online (Sandbox Code Playgroud)
但是如果我在11:00or处运行相同的命令11:05,那么我们得到:
# No scheduled commands are ready to run.
Run Code Online (Sandbox Code Playgroud)
我最终在我的日志文件中输出。
everyFiveMinutes()根据我的任务调度程序每 2 分钟运行一次的事实,我在我的日程安排每 10 分钟在我的文件中创建一个日志时发现了上述情况。
Luc*_*zzi 15
我回答这个问题只是为了让其他人知道(因为我也有同样的困惑)。
Laravel 调度程序与 Linux cron 执行完全相同的工作,通过检查任务的 cronned 时间(以分钟为单位)是否与当前时间完全相同。
当您在 crontab 中设置时,您每分钟* * * * * ... php artisan schedule:run >> ...运行0 秒,例如“1:00:00”、“1:01:00”、“1:02:00”等。schedule:run
因此,如果您在 Laravel 调度程序中将命令设置为在“星期一 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,它将执行您计划在 1:00 运行的任务 N 次。
这就是不需要表或文件来控制进程启动时间的神奇之处。分钟是 cron 中的最小单位,因此除非你做错了事情(例如重复行schedule:run、修改命令运行频率超过一分钟等),否则你的 Laravel 任务将在所需的时间执行一次。
请注意:检查您的时区是否正确config/app.php。我很想知道为什么这样的事情everyMinute(), everyFiveMinutes()有效,但dailyAt('1:10')没有。当然,由于 Laravel 使用 UTC,而我使用 GMT-3(服务器时钟),所以时间上有很大差异。
| 归档时间: |
|
| 查看次数: |
24503 次 |
| 最近记录: |