Laravel入坑指南(番外)——任务调度
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入坑指南(番外)——任务调度的更多相关文章
- Rust入坑指南:核心概念
如果说前面的坑我们一直在用小铲子挖的话,那么今天的坑就是用挖掘机挖的. 今天要介绍的是Rust的一个核心概念:Ownership.全文将分为什么是Ownership以及Ownership的传递类型两部 ...
- electron入坑指南
electron入坑指南 简介 electron 实际集成chrome浏览器和node环境, 运行你写的网页 app 基本目录结构 index.html 名称可以不是index, 这个文件与普通网页的 ...
- C语言入坑指南-被遗忘的初始化
前言 什么是初始化?为什么要初始化?静态变量和局部变量的初始化又有什么区别?实际应用中应该怎么做?本文将一一回答这些问题. 什么是初始化 初始化指的是对数据对象或者变量赋予初始值.例如: int va ...
- Elasticsearch入坑指南之RESTful API
Elasticsearch入坑指南之RESTful API Tags:Elasticsearch ES为开发者提供了非常丰富的基于Http协议的Rest API,通过简单的Rest请求,就可以实现非常 ...
- ElasticSearch入坑指南之概述及安装
---恢复内容开始--- ElasticSearch入坑指南之概述及安装 了解ElasticSearch ElasticSearch(简称ES)基于Lucene的分布式全文检索引擎.使用ES可以实现近 ...
- eclipse中导入外部包却无法查看对应源码或Javadoc的入坑指南
eclipse中导入外部包却无法查看对应源码或Javadoc的 入坑指南 出现这个错误的原因是,你虽然导入了.jar包,但没有配置对应的Javadoc或源码路径,所以在编辑器中无法查看源 码和对应AP ...
- Rust入坑指南:鳞次栉比
很久没有挖Rust的坑啦,今天来挖一些排列整齐的坑.没错,就是要介绍一些集合类型的数据类型."鳞次栉比"这个标题是不是显得很有文化? 在Rust入坑指南:常规套路一文中我们已经介绍 ...
- Rust入坑指南:亡羊补牢
如果你已经开始学习Rust,相信你已经体会过Rust编译器的强大.它可以帮助你避免程序中的大部分错误,但是编译器也不是万能的,如果程序写的不恰当,还是会发生错误,让程序崩溃.所以今天我们就来聊一聊Ru ...
- Rust入坑指南:朝生暮死
今天想和大家一起把我们之前挖的坑再刨深一些.在Java中,一个对象能存活多久全靠JVM来决定,程序员并不需要去关心对象的生命周期,但是在Rust中就大不相同,一个对象从生到死我们都需要掌握的很清楚. ...
- Rust入坑指南:齐头并进(上)
我们知道,如今CPU的计算能力已经非常强大,其速度比内存要高出许多个数量级.为了充分利用CPU资源,多数编程语言都提供了并发编程的能力,Rust也不例外. 聊到并发,就离不开多进程和多线程这两个概念. ...
随机推荐
- mongo-连接失败
连接mongo失败 默认情况下,mongo最大支持65535个连接 查询当前支持的连接数 db.serverStatus.connections { "current" : 3,/ ...
- [转帖]Kubernetes1.25.6部署文档 使用cri-docker部署K8s1.25.6
https://zhuanlan.zhihu.com/p/600808149 本文档将通过kubeadm+docker部署K8s集群,本次集群使用的容器运行工具为docker,K8s的容器运行工具也可 ...
- [转帖]docker-compose完全清除
https://www.cnblogs.com/gelandesprung/p/12112420.html#:~:text=docker-compose%E5%AE%8C%E5%85%A8%E6%B8 ...
- [转帖]Jmeter学习笔记(九)——响应断言
Jmeter学习笔记(九)--响应断言 https://www.cnblogs.com/pachongshangdexuebi/p/11571348.html Jmeter中又一个元件叫断言,用于检查 ...
- [转帖]调优"四剑客"的实战演练,福尔摩斯•K带你轻松优化性能
前言 天下武功,唯快不破.在侦探的世界中,破案效率永远是衡量一名侦探能力的不二法门.作为推理界冉冉升起的新星,大侦探福尔摩斯·K凭借着冷静的头脑.严谨的思维,为我们展现了一场场华丽而热血的推理盛宴. ...
- [转帖]configure: error: cannot guess build type;you must specify one
该问题一般出现在国产平台,从错误描述来看,意思是:无法猜测build类型,你必须指定一个. 解决办法: 1. 在系统/usr路径下搜索 config.guess 和 config.sub 这两个文件. ...
- alertmanager远程配置
用于远程配置alertmanager的rules. 主要步骤为: 通过proxy更新mount的告警规则文件 重启容器 # ./client -h Note: Only for update exis ...
- 【图论,网络流】CF1525F Goblins And Gnomes
Problem Link 你在打怪.你有一个 \(n\) 个点 \(m\) 条边的 DAG,接下来会有 \(k\) 波怪来袭,第 \(i\) 波怪有 \(i\) 个,它们会各自选择走一条路径,要求它们 ...
- windows幻灯片壁纸
设置为10秒 win+r输入regedit 查找路径 HKEY_CURRENT_USER\Control Panel\Personalization\Desktop Slideshow 修改inter ...
- MySQL 中使用变量实现排名名次
title: MySQL 中使用变量实现排名名次 date: 2023-7-16 19:45:26 tags: - SQL 高级查询 一. 数据准备: CREATE TABLE sql_rank ( ...