什么是任务调度
在传统方式下,你需要为每个定时任务手写 cron 条目。 这样做的问题是调度定义脱离源码,无法进行版本管理,每次调整都要 SSH 登录服务器。 Laravel 的调度器允许你在应用内部以流畅的语法定义调度。 只需要在服务器上加一行 cron 条目,其他调度定义都随代码一起进入版本管理。 标准写法是把调度定义写在routes/console.php 里。
使用
schedule:list Artisan 命令可以查看已定义任务的列表以及下一次执行时间。调度器的执行流程
定义调度
调度定义写在routes/console.php。
也可以在 bootstrap/app.php 的 withSchedule 方法中定义。
可调度的任务类型
调度 Artisan 命令
使用command 方法调度 Artisan 命令。可以传入命令名或类名。
调度队列任务
使用job 方法调度队列任务。
无需闭包即可让任务入队,非常方便。
调度 shell 命令
exec 方法用来执行操作系统命令。
调度闭包
call 方法可以调度任意 PHP 闭包。
__invoke 方法的 Invocable 对象。
设置执行频率
常用频率方法
以下是常用的频率方法。直接使用 cron 表达式
也可以通过cron 方法直接使用 cron 表达式。
频率与星期组合
可以把频率方法与星期约束组合出更精细的调度。设置时区
timezone 方法可以为单个任务指定时区。
config/app.php 的 schedule_timezone。
条件约束
when / skip
when 只在闭包返回 true 时执行任务。
skip 相反,返回 true 时跳过。
environments
environments 方法限制任务只在特定环境执行。
时间段约束
between / unlessBetween 可以限制执行的时间段。
星期约束
防止重叠
默认情况下,即便上一次任务尚未结束,下一次执行也会照常开始。 使用withoutOverlapping 会等上一次执行完再开始下一次。
withoutOverlapping 使用应用缓存来管理锁。
如果任务因异常卡死,可以用 schedule:clear-cache 清除锁。多服务器执行控制
多台服务器同时运行调度器时,onOneServer 可以让任务只在其中一台上执行。
onOneServer() 的分布式执行流程
任务分组
如果多个任务共用同样的设置,可以用group 方法一次配置。
后台执行
同一时刻的多个任务默认按定义顺序串行执行。 长任务会拖慢后续任务。runInBackground 会让任务在后台并行执行。
维护模式
应用进入维护模式时,调度任务默认不会执行。 若要强制运行,可使用evenInMaintenanceMode。
维护模式下的处理流程
暂停调度器
无需改代码即可暂停调度器。evenWhenPaused。
适用于健康检查、监控等在维护期仍需运行的任务。
处理输出
输出到文件
sendOutputTo 可以把任务输出写入文件。
appendOutputTo 则会追加到已有文件末尾。
输出到邮件
emailOutputTo 可以把任务输出以邮件发送。
需要事先完成 Laravel 的邮件配置。
emailOutputOnFailure。
任务钩子
before / after 用于在任务前后插入逻辑。
onSuccess / onFailure 用于成功/失败时的钩子。
服务器部署
1
添加 cron 条目
只需在服务器 crontab 中加入下面一行,Laravel 调度器就会每分钟运行。使用
crontab -e 命令编辑。2
确认调度器运行情况
查看已定义任务及下一次执行时间。
本地开发运行
本地开发时可以不使用 cron,而是通过schedule:work 命令让调度器常驻。
Ctrl+C 停止。
亚分钟级调度(间隔小于 1 分钟)
常规 cron 的最小单位是分钟,但 Laravel 支持秒级调度。schedule:run 会持续运行到本分钟结束,处理所有亚分钟任务。
若要在部署时中断正在运行的 schedule:run,可以在部署脚本中加入: