laravel及shell计划任务

Posted 克维拉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了laravel及shell计划任务相关的知识,希望对你有一定的参考价值。

php本身是没有定时功能的,PHP也不能多线程。PHP的定时任务功能必须通过和其他工具结合才能实现

linux 的脚本实现

使用方式 :

crontab   filecrontab [ -u user ] [ -u user ] { -l | -r | -e }

crontab 是用来让使用者在固定时间或固定间隔执行程式之用

使用crontab写shell脚本,然后让PHP调用shell,这个是利用linux的特性,应该还不算PHP自身语言的特性

 

00 * * * * lynx -dump https://www.yourdomain.com/script.php

1列表示分钟1~59 每分钟用或者 */1表示,/n表示每n分钟,例如*/8就是每8分钟的意思,下面也是类推

2列表示小时1~23(0表示0点)

3列表示日期1~31

4列表示月份1~12

5列标识号星期0~6(0表示星期天)

 

意思就是说通过lynx访问这个url。我们在使用中主要用到lynx、curl、wget来实现对url的远程访问,而如果要提高效率,直接用php去执行本地php文件是最佳选择,例如:

00 */2 * * * /usr/local/bin/php /home/www/script.php

这条语句就可以在每2小时的0分钟,通过linux内部php环境执行script.php,注意,这里可不是通过url访问,通过服务器环境来执行哦,而是直接执行,因为绕过了服务器环境,所以效率当然要高很多。

PHP实现

ignore_user_abort(true);

通过url访问这个php的时候,即使用户把浏览器关掉(断开连接)

https://segmentfault.com/a/1190000002955509

laravel的定时任务

 

在以前,开发者需要为每一个需要调度的任务编写一个Cron条目,这是很让人头疼的事。你的任务调度不在源码控制中,你必须使用SSH登录到服务器然后添加这些Cron条目。

 

1开始

任务调度定义在app/Console/Kernel.php文件的schedule方法中,该方法中已经包含了一个示例。你可以自由地添加你需要的调度任务到Schedule对象。

你可以在App\Console\Kernel类的schedule方法中定义所有调度任务。

1在这个例子中,我们将会在每天午夜调度一个被调用的闭包。在这个闭包中我们将会执行一个数据库查询来清空表:

  protected function schedule(Schedule $schedule)

    {

        $schedule->call(function () {

            DB::table(‘recent_users‘)->delete();

        })->daily();

    }

2除了调度闭包调用外,还可以调度Artisan命令和操作系统命令。例如,可以使用command方法通过命令名或类来调度一个Artisan命令:

$schedule->command(‘emails:send --force‘)->daily();

$schedule->command(EmailsCommand::class, [‘--force‘])->daily();

 

3exec命令可用于发送命令到操作系统:

$schedule->exec(‘node /home/forge/script.js‘)->daily();

 

 

 

2调用

开启调度器

下面是你唯一需要添加到服务器的Cron条目,如果你不知道如何添加Cron条目到服务器,可以考虑使用诸如Laravel Forge这样的服务来为管理Cron条目:

* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1

Cron将会每分钟调用一次Laravel命令调度器,然后,Laravel评估你的调度任务并运行到期的任务。

 

 

 

3细节

 

调度常用选项

当然,你可以分配多种调度到任务:

方法描述

->cron(‘* * * * *‘); 在自定义Cron调度上运行任务

->everyMinute(); 每分钟运行一次任务

->everyFiveMinutes(); 每五分钟运行一次任务

->everyTenMinutes(); 每十分钟运行一次任务

->everyThirtyMinutes(); 每三十分钟运行一次任务

->hourly(); 每小时运行一次任务

->daily(); 每天凌晨零点运行任务

->dailyAt(‘13:00‘); 每天13:00运行任务

->twiceDaily(1, 13); 每天1:00 & 13:00运行任务

->weekly(); 每周运行一次任务

->monthly(); 每月运行一次任务

->monthlyOn(4, ‘15:00‘); 每月4号15:00运行一次任务

->quarterly(); 每个季度运行一次

->yearly(); 每年运行一次

->timezone(‘America/New_York‘); 设置时区

 

 

$schedule->call(function () {

    // 每周星期一13:00运行一次...

})->weekly()->mondays()->at(‘13:00‘);

 

// Run hourly from 8 AM to 5 PM on weekdays...

$schedule->command(‘foo‘)

         ->weekdays()

         ->hourly()

         ->timezone(‘America/Chicago‘)

         ->between(‘8:00‘, ‘17:00‘);

 

->weekdays(); 只在工作日运行任务

->sundays(); 每个星期天运行任务

->mondays(); 每个星期一运行任务

->tuesdays(); 每个星期二运行任务

->wednesdays(); 每个星期三运行任务

->thursdays(); 每个星期四运行任务

->fridays(); 每个星期五运行任务

->saturdays(); 每个星期六运行任务

->between($start, $end); 基于特定时间段运行任务

->when(Closure); 基于特定测试运行任务

 

真理测试的约束条件

when方法用于限制任务基于给定真理测试的结果执行。换句话说,如果给定闭包返回true,只要没有其它约束条件阻止任务运行,该任务就会执行:

$schedule->command(‘emails:send‘)->daily()->when(function () {

    return true;

});

 

skip方法和when相反,如果skip方法返回true,调度任务将不会执行:

$schedule->command(‘emails:send‘)->daily()->skip(function () {

    return true;

});

 

4避免任务重叠

默认情况下,即使前一个任务仍然在运行调度任务也会运行,要避免这样的情况,可使用withoutOverlapping方法:

$schedule->command(‘emails:send‘)->withoutOverlapping();

在本例中,Artisan命令emails:send每分钟都会运行,如果该命令没有在运行的话。如果你的任务在执行时经常大幅度的变化,那么withoutOverlapping方法就非常有用,你不必再去预测给定任务到底要消耗多长时间。

 

5结果

任务输出

Laravel调度器为处理调度任务输出提供了多个方便的方法。首先,使用sendOutputTo方法,你可以发送输出到文件以便稍后检查:

$schedule->command(‘emails:send‘)

         ->daily()

         ->sendOutputTo($filePath);

如果你想要追加输出到给定文件,可以使用appendOutputTo方法:

$schedule->command(‘emails:send‘)

         ->daily()

         ->appendOutputTo($filePath);

使用emailOutputTo方法,你可以将输出发送到电子邮件,注意输出必须首先通过sendOutputTo方法发送到文件。还有,使用电子邮件发送任务输出之前,应该配置Laravel的电子邮件服务

$schedule->command(‘foo‘)

         ->daily()

         ->sendOutputTo($filePath)

         ->emailOutputTo(‘[email protected]);

注:emailOutputTo和sendOutputTo方法只对command方法有效,不支持call方法。

6任务钩子

 

1使用beforeafter方法,你可以指定在调度任务完成之前和之后要执行的代码:

$schedule->command(‘emails:send‘)

         ->daily()

         ->before(function () {

             // Task is about to start...

         })

         ->after(function () {

             // Task is complete...

         });

2ping URL

使用pingBeforethenPing方法,调度器可以在任务完成之前和之后自动ping给定的URL。该方法在通知外部服务时很有用,例如Laravel Envoyer,在调度任务开始或完成的时候:

$schedule->command(‘emails:send‘)

         ->daily()

         ->pingBefore($url)

         ->thenPing($url);

使用pingBefore($url)或thenPing($url)特性需要安装HTTPGuzzle,可以使用Composer包管理器来安装Guzzle到项目:

以上是关于laravel及shell计划任务的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 计划任务(任务调度)的使用

Laravel 计划任务(任务调度)的使用

Laravel 运行多个计划任务

shell脚本手动执行无问题,放在计划任务里面就不正常了,请大神指教!

在 Plesk 中运行 Laravel 5.1 任务计划程序

Linux Shell计划任务