Laravel Artisan:`schedule:运行` 是如何工作的?
Laravel Artisan: How does `schedule:run` work?
我设置了一个虚拟命令作业,其handle()
功能如下:
public function handle()
{
$this->line('==================');
$this->line('Running my job at ' . Carbon::now());
$this->line('Ending my job at ' . Carbon::now());
}
如您所见,除了 return 标准输出的几行信息外,它实际上什么也没做。
现在,在我的 App\Console\Kernel
class 中,我设置了以下时间表:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyMinute()
-> appendOutputTo (storage_path().'/logs/laravel_output.log');
}
现在,从command-line我运行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
到目前为止一切顺利。看来我的日程是运行ning。但是,如果我在同一分钟内再次 运行 命令,我的日志文件现在显示为:
==================
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
换句话说,时间表似乎比每分钟都更 运行ning,这在我看来违反了我在时间表中定义的规则。
更令人困惑的是,我可以将时间表更改为每 5 分钟而不是每分钟 运行:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyFiveMinutes()
-> appendOutputTo (storage_path().'/logs/laravel_output.log');
}
然后运行php artisan schedule:run
,然后我得到以下输出
No scheduled commands are ready to run.
我可以等多久(即超过 5 分钟),但我的日志文件仍然没有输出。
当我使用 Windows Task Scheduler 安排我的命令时,我观察到完全相同的行为(是的,我的开发环境是一个 Windows 7 框,是的,这是 Windows 相当于 cron-job).
问题
所以这是怎么回事? artisan schedule:run
命令如何确定要执行的计划中 "waiting" 哪些命令?本来以为会有什么log-file来记录"Command X is on a 1-hour schedule and last ran at 09:00, so don't execute it again before 10:00",但是一直找不到这样的日志的踪迹。
有人可以给我线索吗?
谢谢!!
我知道回答你自己的问题不太酷。无论如何,让我们想象这是我的日程安排:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyFiveMinutes()
-> appendOutputTo ('/my/logs/laravel_output.log');
}
我发现此代码不会将您的作业设置为每 5 分钟 运行。如果 运行 不到 5 分钟前,它也不会再次阻止命令 运行ning。
更好的思考方式是这段代码设置命名命令"to be runnable every time the minute-figure of the current time is 0
or 5
"。换句话说,如果我 运行 命令行参数:php artisan schedule:run
at 11:04
,那么响应是:
# No scheduled commands are ready to run.
但是如果我 运行 在 11:00
或 11:05
处执行相同的命令,那么我们会得到:
# Running scheduled command: php artisan cbh:dummyCommand >> /my/logs/laravel_output.log 2>&1
最后我的日志文件中有输出。
当我的 everyFiveMinutes()
计划每 10 分钟在我的文件中创建一个日志时,我发现了上述情况,因为我的任务计划程序每 2 分钟 运行ning 一次。
我回答这个问题只是为了让其他人知道(因为我也有同样的困惑)。
Laravel 调度程序 与 Linux cron 完成 相同的工作,通过检查任务的 cronned 时间(分钟) 与当前时间完全一致
当您在 crontab * * * * * ... php artisan schedule:run >> ...
中设置时,您每分钟 0 秒 运行ning schedule:run
,例如'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
,它会在1:00执行N次你计划运行的任务。
这就是不需要 table 或文件来控制进程启动时间的神奇之处。分钟是 cron 中的最小单位,所以除非你做错了事(比如复制 schedule:run
行,破解 运行 命令 more often than a minute 等)你的 Laravel 任务将在所需时间执行一次。
请注意:请检查您在 config/app.php
中的时区是否正确。我疯狂地理解为什么像 everyMinute(), everyFiveMinutes()
这样的东西有效,而 dailyAt('1:10')
却没有。当然,UTC 的 Laravel 而我的 GMT-3(服务器时钟),我的小时数有很大差异。
我设置了一个虚拟命令作业,其handle()
功能如下:
public function handle()
{
$this->line('==================');
$this->line('Running my job at ' . Carbon::now());
$this->line('Ending my job at ' . Carbon::now());
}
如您所见,除了 return 标准输出的几行信息外,它实际上什么也没做。
现在,在我的 App\Console\Kernel
class 中,我设置了以下时间表:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyMinute()
-> appendOutputTo (storage_path().'/logs/laravel_output.log');
}
现在,从command-line我运行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
到目前为止一切顺利。看来我的日程是运行ning。但是,如果我在同一分钟内再次 运行 命令,我的日志文件现在显示为:
==================
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
换句话说,时间表似乎比每分钟都更 运行ning,这在我看来违反了我在时间表中定义的规则。
更令人困惑的是,我可以将时间表更改为每 5 分钟而不是每分钟 运行:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyFiveMinutes()
-> appendOutputTo (storage_path().'/logs/laravel_output.log');
}
然后运行php artisan schedule:run
,然后我得到以下输出
No scheduled commands are ready to run.
我可以等多久(即超过 5 分钟),但我的日志文件仍然没有输出。
当我使用 Windows Task Scheduler 安排我的命令时,我观察到完全相同的行为(是的,我的开发环境是一个 Windows 7 框,是的,这是 Windows 相当于 cron-job).
问题
所以这是怎么回事? artisan schedule:run
命令如何确定要执行的计划中 "waiting" 哪些命令?本来以为会有什么log-file来记录"Command X is on a 1-hour schedule and last ran at 09:00, so don't execute it again before 10:00",但是一直找不到这样的日志的踪迹。
有人可以给我线索吗?
谢谢!!
我知道回答你自己的问题不太酷。无论如何,让我们想象这是我的日程安排:
protected function schedule(Schedule $schedule)
{
$schedule
-> command('cbh:dummyCommand')
-> everyFiveMinutes()
-> appendOutputTo ('/my/logs/laravel_output.log');
}
我发现此代码不会将您的作业设置为每 5 分钟 运行。如果 运行 不到 5 分钟前,它也不会再次阻止命令 运行ning。
更好的思考方式是这段代码设置命名命令"to be runnable every time the minute-figure of the current time is 0
or 5
"。换句话说,如果我 运行 命令行参数:php artisan schedule:run
at 11:04
,那么响应是:
# No scheduled commands are ready to run.
但是如果我 运行 在 11:00
或 11:05
处执行相同的命令,那么我们会得到:
# Running scheduled command: php artisan cbh:dummyCommand >> /my/logs/laravel_output.log 2>&1
最后我的日志文件中有输出。
当我的 everyFiveMinutes()
计划每 10 分钟在我的文件中创建一个日志时,我发现了上述情况,因为我的任务计划程序每 2 分钟 运行ning 一次。
我回答这个问题只是为了让其他人知道(因为我也有同样的困惑)。
Laravel 调度程序 与 Linux cron 完成 相同的工作,通过检查任务的 cronned 时间(分钟) 与当前时间完全一致
当您在 crontab * * * * * ... php artisan schedule:run >> ...
中设置时,您每分钟 0 秒 运行ning schedule:run
,例如'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
,它会在1:00执行N次你计划运行的任务。
这就是不需要 table 或文件来控制进程启动时间的神奇之处。分钟是 cron 中的最小单位,所以除非你做错了事(比如复制 schedule:run
行,破解 运行 命令 more often than a minute 等)你的 Laravel 任务将在所需时间执行一次。
请注意:请检查您在 config/app.php
中的时区是否正确。我疯狂地理解为什么像 everyMinute(), everyFiveMinutes()
这样的东西有效,而 dailyAt('1:10')
却没有。当然,UTC 的 Laravel 而我的 GMT-3(服务器时钟),我的小时数有很大差异。