Laravel 任务调度完全指南
Laravel 命令调度器把 cron 收进应用内:闭包/命令/队列任务统一调度,分钟到自定义频率、前后钩子、后台执行、任务监控一站式。本文从配置到实战全覆盖。
本文依据官方文档整理,未执行运行验证或性能基准。代码片段展示局部用法,业务函数、数据和环境需按项目补齐;版本与配置以所引文档为准。
直接回答:Laravel 任务调度用自带的命令调度器——服务器 cron 只需一条每分钟 php artisan schedule:run,所有任务定义在应用代码里(routes/console.php 或 Console Kernel):调度 Artisan 命令、闭包、队列任务,频率从每分钟到自定义 cron 表达式,支持前后钩子与后台执行,配合监控即可感知任务失败或漏跑。
为什么把任务定义放进应用
系统 cron 的局限:任务定义脱离应用代码、随部署漂移、谁改了什么不可追溯。Laravel 调度器把调度收进版本控制——cron 只管每分钟戳一下调度器,所有逻辑在代码里。
* * * * * cd /var/www && php artisan schedule:run >> /dev/null 2>&1
三种调度对象
use Illuminate\Support\Facades\Schedule;
Schedule::command('reports:send')->daily(); // Artisan 命令
Schedule::call(fn () => app(Backup::class)->run())->hourly(); // 闭包
Schedule::job(new SyncOrders)->everyFiveMinutes(); // 队列任务
频率与执行控制
- 频率:
everyMinute()、hourly()、dailyAt('03:30')、weekdays()、或cron('*/10 * * * *')自定义 - 后台执行:
->runInBackground()仅适用于 command/exec 调度,不能直接用于任意闭包或队列 job - 条件:
->when()、->environments('production')、->withoutOverlapping()通过缓存锁防重入 - 钩子:
->before()/->after();command/exec 可使用->onSuccess()/->onFailure()。调度成功派发队列 job 不等于该 job 已执行成功,需由 queue worker 的失败处理与日志另行追踪
查看与排障
php artisan schedule:list 列出全部任务与下次运行时间——排障第一动作。任务不跑按序查:系统 cron 是否生效 → schedule:run 手动执行看报错 → 时区配置(->timezone())。
监控:任务没跑比报错更可怕
任务可能因进程退出或 cron 配置失效而没有执行,不能只搜索错误日志。记录任务名、计划时间、实际完成时间、结果和耗时;队列任务的完成日志应由 worker 写出,而不是在派发时写出。
这些日志经 DataKit 采集后,可在观测云的日志检测中按任务名筛选完成记录,设置覆盖任务最长耗时的检测窗口,并配置数据断档条件。这样,任务失败记录与窗口内没有完成记录可以分别处理;再结合采集器状态区分漏跑和日志未送达。
常见问题(FAQ)
Q:多服务器部署时任务会重复跑吗?
A:会,除非加 ->onOneServer()(需要共享缓存如 Redis 做协调)。单机也须处理任务重入、幂等和锁过期。多实例的共享缓存驱动须支持所需原子锁。
Q:长任务怎么防重叠?
A:->withoutOverlapping() 用锁防止上一次没跑完下一次又起;用 ->withoutOverlapping(10) 指定锁过期分钟数(示例10分钟,不是建议值);必须长于最坏执行时长,否则锁提前过期仍会重叠。确认任务已停止后才用 schedule:clear-cache 清残锁。
Q:秒级调度支持吗?
A:以 Laravel 12 文档为例,支持 everySecond 等次分钟调度;cron 每分钟执行 schedule:run 时,它会持续到本分钟结束,不要求必须 schedule:work。部署后可调用 schedule:interrupt 结束仍运行旧代码的该分钟调度。
官方参考
资料核对日期:2026-09-29。