ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
### 创建任务 在命令行执行下面的命令生产自定义任务文件,比如说创建一个定时取消订单的任务`OrderCancel` ~~~bash php artisan make:command OrderCancel ~~~ 命令执行完后会生成`app/Console/Commands/OrderCancel.php`文件 ### 编写任务 在上一步生成的文件中编写代码,`signature`变量为执行的命令,`handle()`方法中写具体的实现逻辑 ~~~php <?php namespace App\Console\Commands; use Illuminate\Console\Command; class OrderCancel extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'order:cancel'; /** * The console command description. * * @var string */ protected $description = '30分钟未付款取消订单'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed * @throws */ public function handle() { echo 'The order has been cancelled'.PHP_EOL; return true; } } ~~~ ### 启动调度器 #### 执行单个任务 在命令行直接执行自定义的执行命令即可测试方法,例如 ~~~bash php artisan order:cancel ~~~ 会在命令行输出`The order has been cancelled` #### 执行全部任务 在`app/Console/Kernel.php`的`schedule`方法中添加需要执行的全部任务 ~~~php $schedule->command('order:cancel')->everyMinute(); ~~~ 然后执行下面的命令即可 ~~~bash php artisan schedule:run ~~~ `everyMinute()`是任务调度的时间控制,更多用法可以参考 [Laravel入坑指南(番外)——任务调度 - 咚..咚 - 博客园 (cnblogs.com)](https://links.jianshu.com/go?to=https%3A%2F%2Fwww.cnblogs.com%2Fddcoder%2Fp%2F13455177.html) 注意事项:`php artisan schedule:run`这个命令下`echo`不会在控制台打印,可以使用`laravel`自带的`Log`记录 #### 自动执行任务 在`linux`系统的`crontab`中添加下面的任务,每秒执行一次 ~~~bash * * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1 ~~~ 如果需要精确到毫秒级的定时任务,可以自己写shell脚本来执行任务调度 ### 并行执行任务 如果有多个任务调度,一般是顺序执行的,也就是要等第一个任务执行完成第二个才会开始执行,如果要让任务并行执行的话,需要在`schedule`方法中调用`runInBackground()`方法,例如 ~~~php $schedule->command('order:cancel')->everyMinute()->runInBackground(); ~~~ ### 任务重复处理 如果一个任务执行需要5秒时间,但是任务是每秒执行的,就会出现上一次任务还没执行完,同一个任务又开始了,为了避免这种情况,需要在`schedule`方法中调用`withoutOverlapping()`方法,例如 ~~~php $schedule->command('order:cancel')->withoutOverlapping(); //锁默认24小时失效 $schedule->command('order:cancel')->withoutOverlapping(10); //锁10分钟失效 ~~~ 在任务执行的时候会添加一个锁,在加锁状态下任务是不会执行的,知道任务执行完成。当然还可以使用外部的手段来加锁,比如`文件锁flock`,或者`redis的setnx`都可以 ### 输出重定向 在`schedule`方法中调用`appendOutputTo()`方法可以指定输出流的文件 ~~~php $schedule->command('order:cancel')->appendOutputTo($filePath); ~~~ ### 任务钩子 使用 `before` 和 `after` 方法,你可以指定在调度任务完成之前和之后要执行的代码 ~~~php $schedule->command('order:cancel') ->daily() ->before(function () { // 任务即将开始... }) ->after(function () { // 任务已经完成... }); ~~~