Laravel 的计划任务真是比 Linux 系统的 crontab 方便多了

更新日期: 2019-05-08 阅读次数: 15553 字数: 405 分类: Laravel

例如,我想加一个新功能,24小时内未支付的订单自动变更状态。以前都是通过系统 crontab 定时执行,但是缺点很明显。每次都需要手动配置 crontab,不方便在项目中集中管理。

看了一下 Laravel 的 scheduling 确实方便不少。

避免并发执行

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

这里需要注意,对于 call function 定义的计划任务,需要定义 name。否则会报错

production.ERROR: A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'.

正确的做法是

$schedule->call(function () {
            DB::table('recent_users')->delete();
})->daily()
  ->name('project_delete_users')
  ->withoutOverlapping();

编辑任务

app/Console/Kernel.php

protected function schedule(Schedule $schedule)
{
        $schedule->call(function () {
            DB::table('recent_users')->delete();
        })->daily();
}

注意这里使用了匿名函数。

具体实现函数,可以在其他模块中实现,然后在匿名函数中调用。

示例,自动处理过期订单

Order.php

    public static function handle_expired_order() {
        $orders = self::where('status', self::STATUS_NEW)
            ->whereRaw("created_at < NOW() - INTERVAL 1 DAY")
            ->get();

        foreach ($orders as $order) {
            $order->status = self::STATUS_EXPIRED;
            $order->save();
        }
    }

app/Console/Kernel.php

protected function schedule(Schedule $schedule)
    {
        $schedule->call(function () {
            Order::handle_expired_order();
        })->hourly();
    }

每小时执行

->hourly();

本地调试的时候,最好改成

->everyMinute();

方便查看效果。

指定具体哪几个小时执行

例如,如果想在 2 点,7点,10点,13,16,19 点的第 10 分钟执行。类似于 Linux crontab 的语法:

$schedule->call(function () {
	Express::update_all_express_info();
})->cron('10 2,7,10,13,16,19 * * * *')
	->name('appname_update_express')
        ->withoutOverlapping();

最后不要忘了添加系统 crontab

Ubuntu 下,命令行输入

crontab -e

然后在最后加入

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

定期清理数据

$schedule->call(function () {
        VisitHistory::clear_history();
})->dailyAt('03:01');
public static function clear_history() {
       self::whereRaw("updated_at < NOW() - INTERVAL 14 DAY")->delete();
}

参考

测试环境

Laravel 5.5

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式

谈笑风生

柚子

order.php  是写在model层,还是哪里啊?

柚子

Order.php 是写在哪里啊?model层吗?

大象腿

对,写在 model 里