Laravel提供了非常强劲的命令行工具(如果还不了解,传送到第8往篇),我们如果想要定期执行某个命令行,可以利用crontab进行定时设置。如果有多个定期的任务,很简单,我们设定多条crontab规则在不同时间段内调度不同的命令即可。

而Laravel框架内部也提供了这样的调度机制。(当然,还是逃不过crontab的支持)

首先,我们需要在crontab中添加这么一条规则

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

其次,所有的调度任务都在/app/Console/Kernel.php的schedule函数中进行调度设置

这个函数中可以调度闭包、可调用对象(包含__invoke的对象)、artisian命令、列队任务以及shell命令。以下以例子进行说明:

//调度闭包,->daily()即调度选项,每天凌晨零点运行任务
//关于调度选项后面会统一说明
$schedule->call(function () {
DB::table('recent_users')->delete();
})->daily(); //调度可调用对象
//DeleteRecentUsers类中包含了__invoke魔术方法
$schedule->call(new DeleteRecentUsers)->daily(); //调度artisian命令
$schedule->command('emails:send --force')->daily();
$schedule->command(EmailsCommand::class, ['--force'])->daily(); //调度列队任务
$schedule->job(new Heartbeat)->everyFiveMinutes();
$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes(); //将job投递到heartbeats列队中 //调度shell命令
$schedule->exec('node /home/forge/script.js')->daily();

常用的调度选项:

方法 描述
->cron('* * * * *'); 在自定义Cron调度上运行任务
->everyMinute(); 每分钟运行一次任务
->everyFiveMinutes(); 每五分钟运行一次任务
->everyTenMinutes(); 每十分钟运行一次任务
->everyFifteenMinutes(); 每十五分钟运行一次任务
->everyThirtyMinutes(); 每三十分钟运行一次任务
->hourly(); 每小时运行一次任务
->hourlyAt(17); 每小时第十七分钟运行一次任务
->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'); 设置时区

额外调度约束选项:

方法 描述
->weekdays(); 只在工作日运行任务
->weekends(); 只在周末运行任务
->sundays(); 每个星期天运行任务
->mondays(); 每个星期一运行任务
->tuesdays(); 每个星期二运行任务
->wednesdays(); 每个星期三运行任务
->thursdays(); 每个星期四运行任务
->fridays(); 每个星期五运行任务
->saturdays(); 每个星期六运行任务
->between($start, $end); 基于特定时间段运行任务
->when(Closure); 基于特定测试运行任务
->environments($env); 只在指定环境运行任务

举几个例子:

// 每周星期一13:00运行一次...
$schedule->call(function () { })->weekly()->mondays()->at('13:00'); // 工作日的上午8点到下午5点每小时运行...
$schedule->command('foo')
->weekdays()
->hourly()
->timezone('America/Chicago')
->between('8:00', '17:00'); //每天7点到22点之间,每小时运行
$schedule->command('reminders:send')
->hourly()
->between('7:00', '22:00'); //每天23点到4点之外的时间内,每小时运行
$schedule->command('reminders:send')
->hourly()
->unlessBetween('23:00', '4:00'); //when的闭包返回true时运行
$schedule->command('emails:send')->daily()->when(function () {
return true;
}); //skip的闭包返回false时运行
$schedule->command('emails:send')->daily()->skip(function () {
return true;
});

第三,任务调度的重叠处理

当下一次任务开始执行时,万一上一次的任务还没有执行完成,新的任务是会执行的。也就是说,有可能出现多次任务重叠执行的情况。

为了避免这种情况,我们可以使用外部的手段来加锁,比如文件锁flock,或者redis的setnx都可以。但是Laravel非常贴心,已经帮我们准备了这样的机制:

$schedule->command('emails:send')->withoutOverlapping();    //锁默认24小时失效

$schedule->command('emails:send')->withoutOverlapping(10);    //锁10分钟失效

第四,任务调度的顺序

默认情况下,同时调度的多个命令会顺序执行。如果你有一些长时间运行的命令,将会导致随后的命令在预期之后很久才能执行。如果你想要让命令在后台执行以便它们可以同时运,可以使用 runInBackground 方法来实现:

$schedule->command('analytics:report')
->daily()
->runInBackground();

第五,任务输出

我们可以将任务中的输出重定向覆盖写入或追加写入文件中,便于问题的排查:

//覆盖写入
$schedule->command('emails:send')
->daily()
->sendOutputTo($filePath); //追加写入
$schedule->command('emails:send')
->daily()
->appendOutputTo($filePath);

最后,任务钩子

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

$schedule->command('emails:send')
->daily()
->before(function () {
// 任务即将开始...
})
->after(function () {
// 任务已经完成...
});

好了,Laravel话题到这里正式结束了。关于Laravel还有一些知识点,如果想要深入了解的小伙伴就去看官方文档吧。

下周开始,博主会进入另一个话题。至于要写什么,嗯,还没想好,大家下周再见:)

---------------------------  我是可爱的分割线  ----------------------------

最后博主借地宣传一下,漳州编程小组招新了,这是一个面向漳州青少年信息学/软件设计的学习小组,有意向的同学点击链接,联系我吧。

Laravel入坑指南(番外)——任务调度的更多相关文章

  1. Rust入坑指南:核心概念

    如果说前面的坑我们一直在用小铲子挖的话,那么今天的坑就是用挖掘机挖的. 今天要介绍的是Rust的一个核心概念:Ownership.全文将分为什么是Ownership以及Ownership的传递类型两部 ...

  2. electron入坑指南

    electron入坑指南 简介 electron 实际集成chrome浏览器和node环境, 运行你写的网页 app 基本目录结构 index.html 名称可以不是index, 这个文件与普通网页的 ...

  3. C语言入坑指南-被遗忘的初始化

    前言 什么是初始化?为什么要初始化?静态变量和局部变量的初始化又有什么区别?实际应用中应该怎么做?本文将一一回答这些问题. 什么是初始化 初始化指的是对数据对象或者变量赋予初始值.例如: int va ...

  4. Elasticsearch入坑指南之RESTful API

    Elasticsearch入坑指南之RESTful API Tags:Elasticsearch ES为开发者提供了非常丰富的基于Http协议的Rest API,通过简单的Rest请求,就可以实现非常 ...

  5. ElasticSearch入坑指南之概述及安装

    ---恢复内容开始--- ElasticSearch入坑指南之概述及安装 了解ElasticSearch ElasticSearch(简称ES)基于Lucene的分布式全文检索引擎.使用ES可以实现近 ...

  6. eclipse中导入外部包却无法查看对应源码或Javadoc的入坑指南

    eclipse中导入外部包却无法查看对应源码或Javadoc的 入坑指南 出现这个错误的原因是,你虽然导入了.jar包,但没有配置对应的Javadoc或源码路径,所以在编辑器中无法查看源 码和对应AP ...

  7. Rust入坑指南:鳞次栉比

    很久没有挖Rust的坑啦,今天来挖一些排列整齐的坑.没错,就是要介绍一些集合类型的数据类型."鳞次栉比"这个标题是不是显得很有文化? 在Rust入坑指南:常规套路一文中我们已经介绍 ...

  8. Rust入坑指南:亡羊补牢

    如果你已经开始学习Rust,相信你已经体会过Rust编译器的强大.它可以帮助你避免程序中的大部分错误,但是编译器也不是万能的,如果程序写的不恰当,还是会发生错误,让程序崩溃.所以今天我们就来聊一聊Ru ...

  9. Rust入坑指南:朝生暮死

    今天想和大家一起把我们之前挖的坑再刨深一些.在Java中,一个对象能存活多久全靠JVM来决定,程序员并不需要去关心对象的生命周期,但是在Rust中就大不相同,一个对象从生到死我们都需要掌握的很清楚. ...

  10. Rust入坑指南:齐头并进(上)

    我们知道,如今CPU的计算能力已经非常强大,其速度比内存要高出许多个数量级.为了充分利用CPU资源,多数编程语言都提供了并发编程的能力,Rust也不例外. 聊到并发,就离不开多进程和多线程这两个概念. ...

随机推荐

  1. phpcms : Uncaught Error: [] operator not supported for strings... 的解决方案

    打开/phpcms/modules/admin/classes/push_api.class.php,大概在约 141行, $fields_arr = $fields_value = ''; 将它改为 ...

  2. Oracle19c 多字符集支持的PDB

    Oracle19c 多字符集支持的PDB 背景 想在一个数据库里面支持多种字符集 突然发现Oracle12c开始已经可以实现一个CDB下面可以有多个不同字符集的PDB了 所以想着今天验证一下. 环境信 ...

  3. [转帖]拯救关键业务上线:DBA 的惊魂24小时

    一个电话,打破深夜的宁静 9月20日晚上10点 刚完成外地一个重点项目为期2周的现场支持,从机场回家的路上,一阵急促的铃声惊醒了出租车上昏昏欲睡的我,多年的工作经验告诉我这么晚来电一定是出事了,接起电 ...

  4. [转帖]【性能】中断绑定和查看|irqbalance 中断负载均衡|CPU瓶颈

    常用命令 ``` # 查看当前运行情况 service irqbalance status # 终止服务 service irqbalance stop 取消开机启动: chkconfig irqba ...

  5. [转帖]CPU缓存行

    https://www.jianshu.com/p/e338b550850f CPU缓存 执行程序是靠运行CPU执行主存中代码,但是CPU和主存的速度差异是非常大的,为了降低这种差距,在架构中使用了C ...

  6. [转帖]一个小技巧解决笔记本HDMI接口失灵

      https://baijiahao.baidu.com/s?id=1738289993804283647&wfr=spider&for=pc 现如今笔记本的接口是越来越多,哪怕是标 ...

  7. [转帖]docker编译speccpu2017

    实验步骤: 1.下载docker和speccpu2017 2.docker下载镜像,创建容器 3.将下载的宿主机speccpu2017拷贝到docker创建的容器中(docker cp) 4.在doc ...

  8. Docker 部署 Ceph的简单方法

    https://zhuanlan.zhihu.com/p/390377674 学习一下. docker部署 部署的思路和网络架构和前面分布式是一样的,区别在于命令的形式. 在每个节点安装 docker ...

  9. 文心一言 VS 讯飞星火 VS chatgpt (187)-- 算法导论14.1 4题

    四.用go语言,写出一个递归过程 OS-KEY-RANK(T,k),以一棵顺序统计树T和一个关键字k作为输入,要求返回 k 在由 T 表示的动态集合中的秩.假设 T 的所有关键字都不相同. 文心一言, ...

  10. 京东云RASP云原生安全免疫创新实践

    作者:京东云 刘一鑫 1 背景 随着网络攻击事件整体呈上升趋势,应用作为网络入口承载着大量业务和流量,因此成为了安全的重灾区.黑客往往借助自动化的工具以及安全漏洞,对Web进行漏洞扫描和探测,进而利用 ...