我如何在 Laravel 5.# 中以秒的方式使用调度程序?
How can i use scheduler in seconds manner in Laravel 5.#
我正在尝试在 larave 中安排一些任务,但我发现很难每 20 秒安排一次任务。检查 laravel 文档。 laravel schedular秒没这个方法。虽然有
->cron('* * * * * *') "Run the task on a custom Cron schedule",但也没有解决我的问题。
下面是我在 kernal.php 文件中用于调度的代码。
protected function schedule(Schedule $schedule)
{
// need to replace everyMinute() by some other method which can run it every 20 sec
$schedule->call('path\to\controller@method)->everyMinute();
// also tried cron() but didn't workout.
$schedule->call('path\to\controller@method)->cron(*/20 * * * * *);
}
谢谢。
没有任何方法可以立即为您执行此操作,但是已经与您处于相同情况的人提供了一些建议。
->cron(*/20 * * * * *)
实际上是每 20 分钟而不是每 20 秒说 运行。鉴于 cron 不会下降到亚分钟分辨率,这可能是 Laravel 也不支持它的原因。
如果这真的需要 运行 超过每 30 秒那么我会在这里结合两者:Laravel 5 schedule job every 30 seconds and
也就是说,你仍然应该每分钟调用你的命令,但是添加withoutOverlapping()
方法只是为了安全。
然后在您的命令中,您可以 运行 您的代码,休眠 20 秒,再次 运行 休眠 20 秒,然后再次 运行。这显然是在你的代码几乎瞬时到 运行 的前提下工作的。
例如,如果您的代码需要 5 秒才能 运行 然后您睡了 20 秒然后再次 运行 - 您的代码实际上每 25 秒 运行ning 一次。
我想您很清楚这段代码需要多长时间才能完成 运行。如果没有,请手动计时,同时 运行 使用 artisan 命令来获得一个想法 - 这样的事情可能会有所帮助 date && php artisan your:command && date
。
这将在您的 shell、运行 命令中输出日期,然后再次输出日期 - 这包括您可以用来查看 运行.[= 需要多少秒的时间17=]
这将要求您将控制器操作重构为命令或将 sleep()
代码添加到您的控制器操作中。 docs for artisan 命令在这里应该有所帮助。
我建议将其重构为命令,但这取决于您。
//Console command
public function handle()
{
\App\Investment::calculate(); //takes 2 seconds to run
sleep(18); //sleep for 18 seconds to ensure we are only running the command every 20 seconds
\App\Investment::calculate(); //takes 2 seconds to run
sleep(18);
\App\Investment::calculate(); //takes 2 seconds to run
}
//The console scheduler - Kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->call('path\to\controller@method)->everyMinute()->withoutOverlapping();
}
问题是我们不能以秒为单位处理调度程序,但我们可以根据执行所需的时间调用我们的方法次数来自定义 schedule() 方法的关闭时间,例如:
$obj = new ClassName();
$schedule->call(function () use ($obj) {
sleep(3);
//call method calculate time it takes and based on that we can call method number of methods we want
$obj->method(); //call method
sleep(3); // pause of 3 seconds
$obj->method(); //call again
sleep(3);
$obj->method(); //call again
sleep(3);
})->everyMinute();
在这里,我能够根据执行所需的时间在一分钟内调用我的方法三次。
谢谢,我完成了工作。
出于各种原因,我建议采用不同的方法,而不是在 PHP 任务处理程序代码中延迟。一方面,您在处理函数中混合了不同类型的逻辑(时间应该由调度程序处理,而不是在您的任务代码中处理)。此外,如果您在延迟之间的通话花费了大量时间,您的整体时间将会失真(当然,这本身可以通过测量通话持续时间并将其考虑到下一次延迟来克服)。但是在第一次调用中也可能存在一些异常,导致后续调用甚至无法到达。等等
为此,使用 cron 的一种更常见的方法是简单地添加多个 cron 作业,并对每个作业施加越来越长的延迟。所以:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
* * * * * sleep 20 && cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
* * * * * sleep 40 && cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
这样您就可以确保时间表 运行 每 20 秒恰好一次。
您还可以轻松调整频率,而无需更改 PHP 代码。
编辑:补充和完整性;结合以上内容,您必须使用以下方式安排您的任务:
->cron('* * * * *')
这是可行的,因为使用这样的计划,任务总是在计划程序 运行 时被调用。正如调度程序期望的那样,每分钟最多 运行 一次。回溯验证:
Event::expressionPasses (\illuminate\console\Scheduling\Event.php:296)
CronExpression::isDue (\dragonmantank\cron-expression\src\Cron\CronExpression.php:284)
CronExpression::getNextRunDate (\dragonmantank\cron-expression\src\Cron\CronExpression.php:195)
CronExpression::getRunDate (\dragonmantank\cron-expression\src\Cron\CronExpression.php:322)
最近,Spatie 发布了一个包,使您能够以 sub-minute 间隔安排命令。您可以做一些很酷的事情,例如:
protected function shortSchedule(\Spatie\ShortSchedule\ShortSchedule $shortSchedule)
{
// this command will run every second
$shortSchedule->command('artisan-command')->everySecond();
// this command will run every 30 seconds
$shortSchedule->command('another-artisan-command')->everySeconds(30);
// this command will run every half a second
$shortSchedule->command('another-artisan-command')->everySeconds(0.5);
}
在 Laravel 5.7 :-) 绝对工作正常。
加入app/Console/Kernel.php
$seconds = 5;
$schedule->call(function () use ($seconds) {
$dt = Carbon::now();
$x = 60 / $seconds;
do {
// do your function here that takes between 3 and 4 seconds
\Log::debug($x . ' executing at ' . date('Y-m-d H:i:s'));
time_sleep_until($dt->addSeconds($seconds)->timestamp);
} while ($x-- > 1);
})->everyMinute();
我正在尝试在 larave 中安排一些任务,但我发现很难每 20 秒安排一次任务。检查 laravel 文档。 laravel schedular秒没这个方法。虽然有 ->cron('* * * * * *') "Run the task on a custom Cron schedule",但也没有解决我的问题。
下面是我在 kernal.php 文件中用于调度的代码。
protected function schedule(Schedule $schedule)
{
// need to replace everyMinute() by some other method which can run it every 20 sec
$schedule->call('path\to\controller@method)->everyMinute();
// also tried cron() but didn't workout.
$schedule->call('path\to\controller@method)->cron(*/20 * * * * *);
}
谢谢。
没有任何方法可以立即为您执行此操作,但是已经与您处于相同情况的人提供了一些建议。
->cron(*/20 * * * * *)
实际上是每 20 分钟而不是每 20 秒说 运行。鉴于 cron 不会下降到亚分钟分辨率,这可能是 Laravel 也不支持它的原因。
如果这真的需要 运行 超过每 30 秒那么我会在这里结合两者:Laravel 5 schedule job every 30 seconds and
也就是说,你仍然应该每分钟调用你的命令,但是添加withoutOverlapping()
方法只是为了安全。
然后在您的命令中,您可以 运行 您的代码,休眠 20 秒,再次 运行 休眠 20 秒,然后再次 运行。这显然是在你的代码几乎瞬时到 运行 的前提下工作的。 例如,如果您的代码需要 5 秒才能 运行 然后您睡了 20 秒然后再次 运行 - 您的代码实际上每 25 秒 运行ning 一次。
我想您很清楚这段代码需要多长时间才能完成 运行。如果没有,请手动计时,同时 运行 使用 artisan 命令来获得一个想法 - 这样的事情可能会有所帮助 date && php artisan your:command && date
。
这将在您的 shell、运行 命令中输出日期,然后再次输出日期 - 这包括您可以用来查看 运行.[= 需要多少秒的时间17=]
这将要求您将控制器操作重构为命令或将 sleep()
代码添加到您的控制器操作中。 docs for artisan 命令在这里应该有所帮助。
我建议将其重构为命令,但这取决于您。
//Console command
public function handle()
{
\App\Investment::calculate(); //takes 2 seconds to run
sleep(18); //sleep for 18 seconds to ensure we are only running the command every 20 seconds
\App\Investment::calculate(); //takes 2 seconds to run
sleep(18);
\App\Investment::calculate(); //takes 2 seconds to run
}
//The console scheduler - Kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->call('path\to\controller@method)->everyMinute()->withoutOverlapping();
}
问题是我们不能以秒为单位处理调度程序,但我们可以根据执行所需的时间调用我们的方法次数来自定义 schedule() 方法的关闭时间,例如:
$obj = new ClassName();
$schedule->call(function () use ($obj) {
sleep(3);
//call method calculate time it takes and based on that we can call method number of methods we want
$obj->method(); //call method
sleep(3); // pause of 3 seconds
$obj->method(); //call again
sleep(3);
$obj->method(); //call again
sleep(3);
})->everyMinute();
在这里,我能够根据执行所需的时间在一分钟内调用我的方法三次。 谢谢,我完成了工作。
出于各种原因,我建议采用不同的方法,而不是在 PHP 任务处理程序代码中延迟。一方面,您在处理函数中混合了不同类型的逻辑(时间应该由调度程序处理,而不是在您的任务代码中处理)。此外,如果您在延迟之间的通话花费了大量时间,您的整体时间将会失真(当然,这本身可以通过测量通话持续时间并将其考虑到下一次延迟来克服)。但是在第一次调用中也可能存在一些异常,导致后续调用甚至无法到达。等等
为此,使用 cron 的一种更常见的方法是简单地添加多个 cron 作业,并对每个作业施加越来越长的延迟。所以:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
* * * * * sleep 20 && cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
* * * * * sleep 40 && cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
这样您就可以确保时间表 运行 每 20 秒恰好一次。 您还可以轻松调整频率,而无需更改 PHP 代码。
编辑:补充和完整性;结合以上内容,您必须使用以下方式安排您的任务:
->cron('* * * * *')
这是可行的,因为使用这样的计划,任务总是在计划程序 运行 时被调用。正如调度程序期望的那样,每分钟最多 运行 一次。回溯验证:
Event::expressionPasses (\illuminate\console\Scheduling\Event.php:296)
CronExpression::isDue (\dragonmantank\cron-expression\src\Cron\CronExpression.php:284)
CronExpression::getNextRunDate (\dragonmantank\cron-expression\src\Cron\CronExpression.php:195)
CronExpression::getRunDate (\dragonmantank\cron-expression\src\Cron\CronExpression.php:322)
最近,Spatie 发布了一个包,使您能够以 sub-minute 间隔安排命令。您可以做一些很酷的事情,例如:
protected function shortSchedule(\Spatie\ShortSchedule\ShortSchedule $shortSchedule)
{
// this command will run every second
$shortSchedule->command('artisan-command')->everySecond();
// this command will run every 30 seconds
$shortSchedule->command('another-artisan-command')->everySeconds(30);
// this command will run every half a second
$shortSchedule->command('another-artisan-command')->everySeconds(0.5);
}
在 Laravel 5.7 :-) 绝对工作正常。
加入app/Console/Kernel.php
$seconds = 5;
$schedule->call(function () use ($seconds) {
$dt = Carbon::now();
$x = 60 / $seconds;
do {
// do your function here that takes between 3 and 4 seconds
\Log::debug($x . ' executing at ' . date('Y-m-d H:i:s'));
time_sleep_until($dt->addSeconds($seconds)->timestamp);
} while ($x-- > 1);
})->everyMinute();