过去,你可能需要在服务器上为每一个调度任务去创建 Cron 入口。但是这种方式很快就会变得不友好,因为这些任务调度不在源代码中,并且你每次都需要通过 SSH 链接登录到服务器中才能增加 Cron 入口。


Laravel 命令行调度器允许你在 Laravel 中对命令调度进行清晰流畅的定义。且使用这个任务调度器时,你只需要在你的服务器上创建单个 Cron 入口接口。你的任务调度在 app/Console/Kernel.php 的 schedule 方法中进行定义。为了帮助你更好的入门,这个方法中有个简单的例子。

上边是laravel官方对任务调度的解释,简单说就是在linux下项目需要执行多个定时任务时只要编辑一条crontab命令就可以了,具体修改在程序代码里就可以实现。

下边添加一个每日修改推荐文章的功能

1、通过artisan命令生成一个任务调度,运行完会在app/Console/Commands文件夹下生成UpdateSimilarArticle.php文件,如果没有该文件夹的话也会自动生成该文件夹

php artisan make:command UpdateSimilarArticle

2、UpdateSimilarArticle.php文件中有两个参数需要更改

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'UpdateSimilarArticle';
 
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '更新相似文章';
 
    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
        $arr = [...];
        SimilarArticle::where('article_id','>',0)->delete();
        SimilarArticle::insert($arr);
    }

其中$signature是该任务调度的名称,比如我的就改成了UpdateSimilarArticle;$description是描述或者注释,我的改成了’更新推荐文章’,handle中就是你的业务逻辑了,


3、在App\Console\Kernel 类的 schedule 方法中定义所有的调度任务

    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        //
        \App\Console\Commands\UpdateSimilarArticle::class,
 
    ];
 
    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')
        //          ->hourly();
        $schedule->command('UpdateSimilarArticle')->everyMinute();
 
    }

现在$commands中将UpdateSimilarArticle引入进来,然后再$schedule中定义该任务调度command就是上一步中填写的名称。everyMinute()就是每分钟执行一次。也可以设置成每天一次,看你心情,具体参数中文文档中都写有

4、定义crontab命令,‘* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1’这是官方文档上写的,但是我试了试执行不成功,下边是我再网上找的,我试了试是可以执行的

* * * * * /usr/local/php/bin/php  /home/data/blog/artisan schedule:run >> /dev/null 2>&1

'/usr/local/php/bin/php '是我的php安装位置,/home/data/blog/是项目的绝对路径

在本地也可以通过artisan命令手动执行进行测试,

php artisan schedule:run

补充:

最近又遇到了一种场景,就是分布式的情况下任务调度该如何用,如果只在其中一台web服务器上设置定时任务的话,如果该服务器宕机的话定时任务就不能运行了,如果在所有的web服务器上都设置定时任务的话又会出现定时任务重复执行多次的情况,后来发现laravel官方文档中已经提供了解决的方法,有一个onOneServer的方法,但是需要缓存驱动是 memcached 或者 redis。并且所有的服务器必须使用同一个中央缓存服务器通信。原理就是第一个获取到任务的服务器会生成一个原子锁,用来防止其他服务器在同一时刻执行相同任务。具体代码如下

$schedule->command('report:generate')
                ->fridays()
                ->at('17:00')
                ->onOneServer();

这篇使用Laravel任务调度执行多个定时任务的文章就先讲到这里,更多相关资讯欢迎前往并持续关注编程学习网了解。