任务调度 | 综合话题 |《Laravel 5.8 中文文档 5.8》| Laravel China 社区


本站和网页 https://learnku.com/docs/laravel/5.8/scheduling/3924 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

任务调度 | 综合话题 |《Laravel 5.8 中文文档 5.8》| Laravel China 社区
Laravel
话题列表
社区 Wiki
优质外文
招聘求职
Laravel 实战教程
社区文档
登录
注册
Laravel 5.8 中文文档
展开或关闭
前言
发行说明
升级说明
贡献导引
入门指南
安装
配置信息
文件夹结构
Homestead
Valet
部署
核心架构
请求周期
服务容器
服务提供者
Facades
Contracts
基础功能
路由
中间件
CSRF 保护
控制器
请求
响应
视图
URL
Session
表单验证
错误
日志
前端开发
Blade 模板
本地化
前端指南
编译资源 Mix
安全相关
用户认证
API 认证
用户授权
Email 认证
加密解密
哈希
重置密码
综合话题
Artisan 命令行
广播系统
缓存系统
集合
事件系统
文件存储
辅助函数
邮件发送
消息通知
扩展包开发
队列
任务调度
数据库
快速入门
查询构造器
分页
数据库迁移
数据填充
Redis
Eloquent ORM
快速入门
模型关联
Eloquent 集合
修改器
API 资源
序列化
测试相关
快速入门
HTTP 测试
命令行测试
数据库测试
测试模拟器 Mocking
官方扩展包
Cashier 交易工具包
浏览器测试 Dusk
Envoy 部署工具
Horizon 队列管理工具
Passport OAuth 认证
Scout 全文搜索
Socialite 社会化登录
Telescope 应用调试工具
Laravel
首页
Laravel
Go
PHP
Vue.js
Python
Java
MySQL
Rust
LK
Elasticsearch
F2E 前端
Server
程序员
Database
DevTools
Computer Science
手机开发
AdonisJS
社区
Wiki
教程
Laravel 实战教程首页
《L01 Laravel 教程 - Web 开发实战入门》
《L02 Laravel 教程 - Web 开发实战进阶》
《L03 Laravel 教程 - 实战构架 API 服务器》
《L04 Laravel 教程 - 微信小程序从零到发布》
《L05 Laravel 教程 - 电商实战》
《L06 Laravel 教程 - 电商进阶》
《LX1 Laravel / PHP 扩展包视频教程》
《LX2 PHP 扩展包实战教程 - 从入门到发布》
《L07 Laravel 教程 - Laravel TDD 测试实战》
《LX3 Laravel 性能优化入门》
《LX4 Laravel / PHP 五分钟视频》
文档
社区文档首页
《Laravel 中文文档》
《Laravel 速查表》
《PHP 代码简洁之道》
《Laravel 编码技巧》
《Dcat Admin 中文文档》
《Laravel Nova 中文文档》
《Lumen 中文文档》
《Dingo API 中文文档》
《 Laravel 项目开发规范》
《构建 Laravel 开发环境》
登录
注册
微信登录
提交改进
任务调度
5.8
9.x
8.5
8.x
7.x
6.x
5.8
5.7
5.6
5.5
5.4
5.3
5.2
5.1
Laravel 5.8 中文文档
未匹配的标注
本文档最新版为 9.x,旧版本可能放弃维护,推荐阅读最新版!
任务调度
简介
定义调度
Artisan 命令调度
队列任务调度
Shell 命令调度
调度频率设置
时区
避免任务 重复
任务只运行在一台服务器上
后台任务
维护模式
任务输出
任务钩子
简介
过去,你可能需要在服务器上为每一个调度任务去创建 Cron 入口。但是这种方式很快就会变得不友好,因为这些任务调度不在源代码中,并且你每次都需要通过 SSH 链接登录到服务器中才能增加 Cron 入口。
Laravel 命令行调度器允许你在 Laravel 中对命令调度进行清晰流畅的定义。且使用这个任务调度器时,你只需要在你的服务器上创建单个 Cron 入口接口。你的任务调度在 app/Console/Kernel.php 的 schedule 方法中进行定义。为了帮助你更好的入门,这个方法中有个简单的例子。
启动调度器
当使用这个调度器时,你只需要把下面的 Cron 入口添加到你的服务器中即可。如果你不知道怎么在服务器中添加 Cron 入口,可以考虑使用一些服务来管理 Cron 入口,比如 Laravel Forge:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
这个 Cron 为每分钟执行一次 Laravel 的命令行调度器。当 schedule:run 命令被执行的时候,Laravel 会根据你的调度执行预定的程序。
定义调度
你可以在 App\Console\Kernel 类的 schedule 方法中定义所有的调度任务。在开始之前,让我们来看一个例子。在这个例子中,我们计划每天午夜调用一个闭包。在闭包中,我们执行一个数据库查询来清空一张表:
<?php
namespace App\Console;
use Illuminate\Support\Facades\DB;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
/**
* 应用里的自定义 Artisan 命令
* @var array
*/
protected $commands = [
//
];
/**
* 定义计划任务
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
$schedule->call(function () {
DB::table('recent_users')->delete();
})->daily();
除了使用闭包来定义任务调度外,你也可以用 invokable objects。
$schedule->call(new DeleteRecentUsers)->daily();
Artisan 命令调度
除了使用调用闭包这种方式来调度外,你还可以调用 Artisan 命令 和操作系统命令。比如,你可以给 command 方法传递命令名称或者类来调度一个 Artisan 命令。
$schedule->command('emails:send --force')->daily();
$schedule->command(EmailsCommand::class, ['--force'])->daily();
队列任务调度
job 方法可以用来调度 队列任务。此方法提供了一种快捷的方式来调度任务,而无需使用 call 方法创建闭包来调度任务。
$schedule->job(new Heartbeat)->everyFiveMinutes();
// 分发任务到「heartbeats」队列...
$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();
Shell 命令调度
exec 方法可用于向操作系统发送命令:
$schedule->exec('node /home/forge/script.js')->daily();
调度频率设置
当然了,你可以给你的任务分配多种调度计划:
方法
描述
->cron('* * * * *');
自定义 Cron 时间表执行任务
->everyMinute();
每分钟执行一次任务
->everyFiveMinutes();
每五分钟执行一次任务
->everyTenMinutes();
每十分钟执行一次任务
->everyFifteenMinutes();
每十五分钟执行一次任务
->everyThirtyMinutes();
每三十分钟执行一次任务
->hourly();
每小时执行一次任务
->hourlyAt(17);
每小时第 17 分钟执行一次任务
->daily();
每天午夜执行一次任务(译者注:每天零点)
->dailyAt('13:00');
每天 13 点执行一次任务
->twiceDaily(1, 13);
每天 1 点 和 13 点分别执行一次任务
->weekly();
每周执行一次任务
->weeklyOn(1, '8:00');
每周一的 8 点执行一次任务
->monthly();
每月执行一次任务
->monthlyOn(4, '15:00');
每月 4 号的 15 点执行一次任务
->quarterly();
每季度执行一次任务
->yearly();
每年执行一次任务
->timezone('America/New_York');
设定时区
结合其他一些特定条件,我们可以生成在一周中特定时间运行的任务。举个例子,在每周一执行命令:
// 每周一 13:00 执行...
$schedule->call(function () {
//
})->weekly()->mondays()->at('13:00');
// 工作日(周一至周五) 8点 至 17 点每小时执行一次...
$schedule->command('foo')
->weekdays()
->hourly()
->timezone('America/Chicago')
->between('8:00', '17:00');
额外的限制条件列表如下:
方法
描述
->weekdays();
限制任务在工作日执行
->weekends();
限制任务在周末执行
->sundays();
限制任务在周日执行
->mondays();
限制任务在周一执行
->tuesdays();
限制任务在周二执行
->wednesdays();
限制任务在周三执行
->thursdays();
限制任务在周四执行
->fridays();
限制任务在周五执行
->saturdays();
限制任务在周六执行
->between($start, $end);
限制任务在 $start 和 $end 之间执行
->when(Closure);
当闭包返回为真时执行
->environments($env);
限制任务在特定环境中执行
时间范围限制
使用 between 来限制任务在一天中的某个时间段来执行:
$schedule->command('reminders:send')
->hourly()
->between('7:00', '22:00');
或者使用 unlessBetween 方法来为任务排除一个时间段:
$schedule->command('reminders:send')
->hourly()
->unlessBetween('23:00', '4:00');
闭包测试限制
使用 when 方法来根据测试结果来执行任务。也就是说,如果给定的闭包返回结果为 true,只要没有其他约束条件阻止任务运行,任务就会一直执行下去:
$schedule->command('emails:send')->daily()->when(function () {
return true;
});
skip 方法可以看做是 when 方法的逆过程。如果 skip 方法返回 true,任务就不会执行:
$schedule->command('emails:send')->daily()->skip(function () {
return true;
});
使用链式调用 when 方法时,只有所有的 when 都返回 true 时,任务才会执行。
环境约束
environments 方法可用于仅在给定环境中执行任务:
$schedule->command('emails:send')
->daily()
->environments(['staging', 'production']);
时区
使用 timezone 方法,你可以指定任务在给定的时区内执行:
$schedule->command('report:generate')
->timezone('America/New_York')
->at('02:00')
如果要为所有计划任务分配相同的时区,则可能希望在 app/Console/Kernel.php 文件中定义 scheduleTimezone 方法。 此方法应返回应分配给所有计划任务的默认时区:
/**
* 获取默认情况下应为预定事件使用的时区。
* @return \DateTimeZone|string|null
*/
protected function scheduleTimezone()
return 'America/Chicago';
注意:请记住,有些时区会使用夏令时。当夏时制时间发生更改时,你的任务可能会执行两次,甚至根本不会执行。所以我们建议尽可能避免使用时区来安排计划任务。
避免任务重复
默认情况下,即使之前的任务还在执行,调度内任务也会执行。你可以使用 withoutOverlapping 方法来避免这种情况:
$schedule->command('emails:send')->withoutOverlapping();
在这个例子中,如果 emails:send Artisan 命令 没有正在运行,它将会每分钟执行一次。如果你的任务执行时间不确定,且你又不能准确预估出任务的执行时间,那么 withoutOverlapping 方法会显得特别有用。
如果有需要,你可以指定「without overlapping」锁指定的时间范围。默认情况下,锁将在 24 小时后过期。
$schedule->command('emails:send')->withoutOverlapping(10);
任务只运行在一台服务器上
注意:要使用这个特性,你的应用默认缓存驱动必须是 memcached 或者 redis。除此之外,所有的服务器必须使用同一个中央缓存服务器通信。
如果你的应用在多个服务器上运行,你可能需要限制你的调度任务只在单个服务器上运行。假设你有一个调度任务:每周五晚生成一份新报告。如果这个任务调度器在三个服务器上运行,那么这个任务会在三台服务器上运行且生成三份报告。这样不好!
为了说明任务应该在单个服务器上运行,在定义调度任务时使用 onOneServer 方法。第一个获取到任务的服务器会生成一个原子锁,用来防止其他服务器在同一时刻执行相同任务。
$schedule->command('report:generate')
->fridays()
->at('17:00')
->onOneServer();
后台任务
默认情况下,同时调度的多个命令将按顺序执行。如果你有长时间运行的命令,这可能会导致后续命令的启动时间比预期的要晚。因此,你想在后台同时运行命令,可以使用 runInBackground 方法:
$schedule->command('analytics:report')
->daily()
->runInBackground();
维护模式
Laravel 的队列任务在 维护模式 下不会运行。因为我们不想你的调度任务干扰到你服务器上可能还未完成的项目。不过,如果你确实是想在维护模式下强制调度任务执行,你可以使用 evenInMaintenanceMode 方法:
$schedule->command('emails:send')->evenInMaintenanceMode();
任务输出
Laravel 调度器提供了一些方便的方法来处理调度任务输出。首先,你可以使用 sendOutputTo 方法来输出到文件以便于后续检查:
$schedule->command('emails:send')
->daily()
->sendOutputTo($filePath);
如果希望将输出 附加 到给定文件,可以使用 appendOutputTo 方法
$schedule->command('emails:send')
->daily()
->appendOutputTo($filePath);
使用 emailOutputTo 方法,你可以将输出发送到指定邮箱。在使用邮件发送之前,你需要配置 Laravel 的 邮件服务:
$schedule->command('foo')
->daily()
->sendOutputTo($filePath)
->emailOutputTo('foo@example.com');
注意:emailOutputTo,sendOutputTo 和 appendOutputTo 方法是 command 和 exec 独有的。
任务钩子
使用 before 和 after 方法,你可以在调度任务执行前或者执行后来执行特定代码:
$schedule->command('emails:send')
->daily()
->before(function () {
// Task is about to start...
})
->after(function () {
// Task is complete...
});
Ping 网址
使用 pingBefore 和 thenPing 方法,你可以在任务执行前或者执行后来 ping 指定的 URL。这个方法在通知外部服务(比如 Laravel Envoyer)时将会特别有用:
$schedule->command('emails:send')
->daily()
->pingBefore($url)
->thenPing($url);
只有在给定条件为 true 时,才能使用 pingBeforeIf 和 thenPingIf 方法 ping 指定的 URL:
$schedule->command('emails:send')
->daily()
->pingBeforeIf($condition, $url)
->thenPingIf($condition, $url);
所有 ping 方法都需要 Guzzle HTTP 库。你可以使用 Composer 来添加 Guzzle 到你的项目中:
composer require guzzlehttp/guzzle
本文章首发在 LearnKu.com 网站上。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
原文地址:https://learnku.com/docs/laravel/5.8/sch...
译文地址:https://learnku.com/docs/laravel/5.8/sch...
上一篇
下一篇
Markdown 文本
纠错改进
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
贡献者:4
推荐文章:
更多推荐...
博客
用Go实现支持多种协议的抓包工具——Shermie-Proxy
22
33
5个月前
博客
国密招商银行对接
29
23
6个月前
博客
php开发的js逆向rpc框架
15
7个月前
博客
强一致性的分布式事务几种模式对比(php有了新方案)
31
19
1年前
博客
基于DTM分布式事务管理的PHP客户端
16
1年前
博客
Laravel基于RT模式实现分布式事务(突破技术支持子服务嵌套事务)
81
39
1年前
讨论数量: 16
发起讨论
只看当前版本
jaak
4年前
调度频率设置中的第一条 cron ('* * * * * *') 疑问
个点赞 | 2 个回复 |
问答
| 课程版本 5.5
南巷以南丶
4年前
关于任务调度的这个方法->dailyAt ('13:00')?
个点赞 | 9 个回复 |
问答
| 课程版本 5.4
ZsmHub
1年前
laravel 定时任务脚本还没跑完,此时如果修改该定时任务脚本的代码,然后直接发版,旧定时任务脚本会怎样呢
个点赞 | 8 个回复 |
问答
| 课程版本 5.8
终生学习者
4年前
定时任务毫秒级,是否可以不用 crontable?比如 swoole,但是方法里确没有毫秒的方法,是否有其他的方案?
个点赞 | 8 个回复 |
问答
| 课程版本 5.7
kiyoma
3年前
任务调度是否是单线程执行的?
个点赞 | 7 个回复 |
问答
| 课程版本 5.5
Daemon
3年前
Laravel 的任务调度在 Windows 下有用吗?
个点赞 | 5 个回复 |
问答
| 课程版本 5.5
dakai
9个月前
如何把commands[]的注册动态的放到schedule当中?或者说如何把kernel的相关内容放到数据库实现可配置化?
个点赞 | 4 个回复 |
问答
| 课程版本 6.x
kiyoma
2年前
$schedule->exec () 执行 shell 命令的所在目录环境是什么?
个点赞 | 3 个回复 |
问答
| 课程版本 5.5
bei_l
2年前
守护进程运行过程中出现部分重复性被插入
个点赞 | 2 个回复 |
问答
| 课程版本 5.8
赤色圣战
3年前
自定义计划任务里多个 $schedule,有一个没有按时执行?
个点赞 | 2 个回复 |
问答
| 课程版本 5.8
bigbug-gg
3年前
Laravel 调度没生效? 试试填写 PHP 绝对路径
个点赞 | 1 个回复 |
分享
| 课程版本 5.5
努力的Charlie
4年前
执行任务调度?
个点赞 | 1 个回复 |
问答
| 课程版本 5.6
Tonoy_Miss
4年前
Laravel 任务调度 cron () 方法为什么有六个*的疑问?
个点赞 | 1 个回复 |
问答
| 课程版本 5.4
bei_l
2年前
任务调度执行了不相关的任务
个点赞 | 0 个回复 |
分享
| 课程版本 5.8
longren610
3年前
设置了任务调度后,在路由中使用 Artisan::call 调用命令返回 500 错误。
个点赞 | 0 个回复 |
问答
| 课程版本 5.8
heirychen
3年前
翻译问题
个点赞 | 0 个回复 |
分享
| 课程版本 5.8
社区赞助商
成为赞助商
关于 LearnKu
LearnKu 是终身编程者的修道场
做最专业、严肃的技术论坛
LearnKu 诞生的故事
资源推荐
《社区使用指南》
《文档撰写指南》
《LearnKu 社区规范》
《提问的智慧》
服务提供商
其他信息
成为版主
所有测验
联系站长(反馈建议)
粤ICP备18099781号-6
粤公网安备 44030502004330号
违法和不良信息举报
由 Summer 设计和编码 ❤
请登录
提交
忘记密码?
or
注册
第三方账号登录
微信登录
GitHub 登录
内容举报
匿名举报,为防止滥用,仅管理员可见举报者。
我要举报该,理由是:
垃圾广告:恶意灌水、广告、推广等内容
无意义内容:测试、灌水、文不对题、消极内容、文章品质太差等
违规内容:色情、暴利、血腥、敏感信息等
不友善内容:人身攻击、挑衅辱骂、恶意行为
科学上网:翻墙、VPN、Shadowsocks,政策风险,会被关站!
不懂提问:提问太随意,需要再做一遍《提问的智慧》测验
随意提问:提问没有发布在社区问答分类下
排版混乱:没有合理使用 Markdown 编写文章,未使用代码高亮
内容结构混乱:逻辑不清晰,内容混乱,难以阅读
标题随意:标题党、标题不释义
尊重版权:分享付费课程、破解软件(付费),侵犯作者劳动成果
其他理由:请补充说明
举报
取消