cron 配置6`*`错误
相关信息:
- 类型:文档文章
- 文章: 任务调度
- 文档: 《Laravel 5.5 中文文档(5.5)》
此投稿已在 4年前 合并。
内容修改:
Old | New | Differences |
---|---|---|
1 | # Laravel 的任务调度(计划任务)功能 Task Scheduling | |
1 | # Laravel 的任务调度(计划任务)功能 Task Scheduling | |
2 | ||
3 | - [简介](#introduction) | |
4 | ||
5 | - [定义调度](#defining-schedules) | |
6 | ||
7 | - [Artisan 命令调度](#scheduling-artisan-commands) | |
8 | - [队列任务调度](#scheduling-queued-jobs) | |
9 | - [Shell 调度命令](#scheduling-shell-commands) | |
10 | - [调度频率设置](#schedule-frequency-options) | |
11 | - [避免任务重复](#preventing-task-overlaps) | |
12 | - [维护模式](#maintenance-mode) | |
13 | ||
14 | - [任务输出](#task-output) | |
15 | - [任务钩子](#task-hooks) | |
16 | ||
17 | <a name="introduction"></a> | |
18 | ## 简介 | |
19 | ||
20 | 在过去,开发者必须在服务器上为每个任务生成单独的 Cron 项目。而令人头疼的是任务调度不受源代码控制,而且必须通过 SSH 连接到服务器上来增加 Cron 项目。 | |
21 | ||
22 | Laravel 的命令调度程序允许你在 Laravel 中对命令调度进行清晰流畅的定义。并且在使用调度程序时,只需要在服务器上增加一条 Cron 项目即可。调度是在 `app/Console/Kernel.php` 文件的 `schedule` 方法中定义的。为了方便你开始,该方法已经包含了一个简单的例子。 | |
23 | ||
24 | ### 启动调度器 | |
25 | ||
26 | 使用调度器时,只需将以下 Cron 项目添加到服务器。如果你不知道如何将 Cron 项目添加到服务器,可以考虑使用 [Laravel Forge](https://forge.laravel.com) 等服务来管理你的 Cron 项目: | |
27 | ||
28 | ```` | |
29 | * * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1 | |
30 | ```` | |
31 | ||
32 | 上面这个 Cron 会每分钟调用一次 Laravel 命令调度器。执行 `schedule:run` 命令时, Laravel 会根据你的调度运行预定任务。 | |
33 | ||
34 | <a name="defining-schedules"></a> | |
35 | ## 定义调度 | |
36 | ||
37 | 你可以在 `App\Console\Kernel` 类的 `schedule` 方法中定义所有调度任务。在开始之前,先看看一个调度任务的例子。在该例子中,我们将计划在每天午夜调用一个 `Closure`。在这个 `Closure` 中,将执行一个数据库查询来清除一个表: | |
38 | ||
39 | ```` | |
40 | <?php | |
41 | ||
42 | namespace App\Console; | |
43 | ||
44 | use DB; | |
45 | use Illuminate\Console\Scheduling\Schedule; | |
46 | use Illuminate\Foundation\Console\Kernel as ConsoleKernel; | |
47 | ||
48 | class Kernel extends ConsoleKernel | |
49 | { | |
50 | /** | |
51 | * 应用提供的 Artisan 命令 | |
52 | * | |
53 | * @var array | |
54 | */ | |
55 | protected $commands = [ | |
56 | \App\Console\Commands\Inspire::class, | |
57 | ]; | |
58 | ||
59 | /** | |
60 | * 定义应用的命令调度 | |
61 | * | |
62 | * @param \Illuminate\Console\Scheduling\Schedule $schedule | |
63 | * @return void | |
64 | */ | |
65 | protected function schedule(Schedule $schedule) | |
66 | { | |
67 | $schedule->call(function () { | |
68 | DB::table('recent_users')->delete(); | |
69 | })->daily(); | |
70 | } | |
71 | } | |
72 | ```` | |
73 | ||
74 | <a name="scheduling-artisan-commands"></a> | |
75 | ||
76 | ### Artisan 命令调度 | |
77 | ||
78 | 除了计划 `Closure` 调用,你还能调度 [Artisan 命令](/docs/{{version}}/artisan) 和操作系统命令。举个例子,你可以给 `command` 方法传递命令名称或者类名称来调度一个 `Artisan` 命令: | |
79 | ||
80 | ```` | |
81 | $schedule->command('emails:send --force')->daily(); | |
82 | ||
83 | $schedule->command(EmailsCommand::class, ['--force'])->daily(); | |
84 | ```` | |
85 | <a name="scheduling-queued-jobs"></a> | |
86 | ||
87 | ### 队列任务调度 | |
88 | ||
89 | `job` 方法可以用来调度 [队列任务](/docs/{{version}}/queues)。这个方法提供了一种快捷方式来调度任务,无需使用 `call` 方法手动创建闭包来调度任务: | |
90 | ||
91 | ```` | |
92 | $schedule->job(new Heartbeat)->everyFiveMinutes(); | |
93 | ```` | |
94 | ||
95 | <a name="scheduling-shell-commands"></a> | |
96 | ### Shell 命令调度 | |
97 | ||
98 | `exec` 方法可用于向操作系统发出命令: | |
99 | ||
100 | ```` | |
101 | $schedule->exec('node /home/forge/script.js')->daily(); | |
102 | ```` | |
103 | ||
104 | <a name="schedule-frequency-options"></a> | |
105 | ### 调度频率设置 | |
106 | ||
107 | 当然,你可以为你的任务分配多种调度计划: | |
108 | ||
109 | | 方法 | 描述 | | |
110 | | --------------------------------- | ------------------------- | | |
111 | | `->cron('* * * * *');` | 在自定义的 Cron 时间表上执行该任务 | | |
112 | | `->everyMinute();` | 每分钟执行一次任务 | | |
113 | | `->everyFiveMinutes();` | 每五分钟执行一次任务 | | |
114 | | `->everyTenMinutes();` | 每十分钟执行一次任务 | | |
115 | | `->everyFifteenMinutes();` | 每十五分钟执行一次任务 | | |
116 | | `->everyThirtyMinutes();` | 每半小时执行一次任务 | | |
117 | | `->hourly();` | 每小时执行一次任务 | | |
118 | | `->hourlyAt(17);` | 每小时的第 17 分钟执行一次任务 | | |
119 | | `->daily();` | 每天午夜执行一次任务 | | |
120 | | `->dailyAt('13:00');` | 每天的 13:00 执行一次任务 | | |
121 | | `->twiceDaily(1, 13);` | 每天的 1:00 和 13:00 分别执行一次任务 | | |
122 | | `->weekly();` | 每周执行一次任务 | | |
123 | | `->monthly();` | 每月执行一次任务 | | |
124 | | `->monthlyOn(4, '15:00');` | 在每个月的第四天的 15:00 执行一次任务 | | |
125 | | `->quarterly();` | 每季度执行一次任务 | | |
126 | | `->yearly();` | 每年执行一次任务 | | |
127 | | `->timezone('America/New_York');` | 设置时区 | | |
128 | ||
129 | 这些方法可以合并其它限制条件以生成更精确的调度。例如,计划每周周一的调度: | |
130 | ||
131 | ```` | |
132 | // 每周一的下午一点钟运行 | |
133 | $schedule->call(function () { | |
134 | // | |
135 | })->weekly()->mondays()->at('13:00'); | |
136 | ||
137 | // 周一至周五上午 8 点至下午 5 点每小时运行一次... | |
138 | $schedule->command('foo') | |
139 | ->weekdays() | |
140 | ->hourly() | |
141 | ->timezone('America/Chicago') | |
142 | ->between('8:00', '17:00'); | |
143 | ```` | |
144 | ||
145 | 以下是额外限制条件的列表: | |
146 | ||
147 | | 方法 | 描述 | | |
148 | | -------------------------- | ----------------- | | |
149 | | `->weekdays();` | 将任务限制在工作日 | | |
150 | | `->sundays();` | 将任务限制在星期天 | | |
151 | | `->mondays();` | 将任务限制在星期一 | | |
152 | | `->tuesdays();` | 将任务限制在星期二 | | |
153 | | `->wednesdays();` | 将任务限制在星期三 | | |
154 | | `->thursdays();` | 将任务限制在星期四 | | |
155 | | `->fridays();` | 将任务限制在星期五 | | |
156 | | `->saturdays();` | 将任务限制在星期六 | | |
157 | | `->between($start, $end);` | 限制任务运行在开始到结束时间范围内 | | |
158 | | `->when(Closure);` | 根据闭包函数的返回来限制任务 | | |
159 | ||
160 | #### 时间范围限制 | |
161 | ||
162 | `between` 方法可以用来限制一天中某个时间范围内的任务执行: | |
163 | ||
164 | ```` | |
165 | $schedule->command('reminders:send') | |
166 | ->hourly() | |
167 | ->between('7:00', '22:00'); | |
168 | ```` | |
169 | ||
170 | 类似的,`unlessBetween` 方法可以用来在一段时间内排除任务的执行: | |
171 | ||
172 | ```` | |
173 | $schedule->command('reminders:send') | |
174 | ->hourly() | |
175 | ->unlessBetween('23:00', '4:00'); | |
176 | ```` | |
177 | ||
178 | #### 闭包测试限制 | |
179 | ||
180 | `when` 方法可以用来根据给定的测试的结果来限制任务的执行。换句话说,如果给定的 `Closure` 返回 `true`,那么只要没有其他约束条件阻止任务运行,任务就会执行: | |
181 | ||
182 | ```` | |
183 | $schedule->command('emails:send')->daily()->when(function () { | |
184 | return true; | |
185 | }); | |
186 | ```` | |
187 | ||
188 | `skip` 方法可以被看作是 `when` 的逆过程。如果 `skip` 方法返回 `true` 的话,那么任务将不会运行: | |
189 | ||
190 | ```` | |
191 | $schedule->command('emails:send')->daily()->skip(function () { | |
192 | return true; | |
193 | }); | |
194 | ```` | |
195 | ||
196 | 当链式调用多个 `when` 方法时,调度命令只有在所有的 `when` 条件返回 `true` 时才运行。 | |
197 | ||
198 | <a name="preventing-task-overlaps"></a> | |
199 | ### 避免任务重复 | |
200 | ||
201 | 默认情况,即便有相同的任务还在运行,调度内的任务依旧会被执行。为了避免这个问题,你可以使用 `withoutOverlapping` 方法: | |
202 | ||
203 | ```` | |
204 | $schedule->command('emails:send')->withoutOverlapping(); | |
205 | ```` | |
206 | ||
207 | 在上面这个例子中,如果没有其它 [Artisan 命令](/docs/{{version}}/artisan) `emails:send` 在运行的话,此任务将于每分钟被运行一次。如果你的任务在执行时间上有很大的不同,你无法准确预测给定任务需要多长时间,`withoutOverlapping` 方法将会特别有帮助。 | |
208 | ||
209 | <a name="maintenance-mode"></a> | |
210 | ### 维护模式 | |
211 | ||
212 | 当 Laravel 处于 [维护模式](/docs/{{version}}/configuration#maintenance-mode) 时,Laravel 的调度功能将不会生效。这是因为我们不想让任务调度干扰你服务器上可能还未完成的项目。然而,如果你想强制某个任务在维护模式下运行的话,你可以使用 `evenInMaintenanceMode` 方法: | |
213 | ||
214 | ```` | |
215 | $schedule->command('emails:send')->evenInMaintenanceMode(); | |
216 | ```` | |
217 | ||
218 | <a name="task-output"></a> | |
219 | ## 任务输出 | |
220 | ||
221 | Laravel 调度器提供了几个方便的方法来处理调度任务生成的输出。首先,使用 `sendOutputTo` 方法可以将输出发送到单个文件上以便后续检查: | |
222 | ||
223 | ```` | |
224 | $schedule->command('emails:send') | |
225 | ->daily() | |
226 | ->sendOutputTo($filePath); | |
227 | ```` | |
228 | ||
229 | 如果想将输出附加到指定的文件上,则可以使用 `appendOutputTo` 方法: | |
230 | ||
231 | ```` | |
232 | $schedule->command('emails:send') | |
233 | ->daily() | |
234 | ->appendOutputTo($filePath); | |
235 | ```` | |
236 | ||
237 | 使用 `emailOutputTo` 方法,你可以通过电子邮件将输出发送到你所指定的邮箱上。在发送任务的输出之前,你应该先配置 Laravel 的 [电子邮件服务](/docs/{{version}}/mail): | |
238 | ||
239 | ```` | |
240 | $schedule->command('foo') | |
241 | ->daily() | |
242 | ->sendOutputTo($filePath) | |
243 | ->emailOutputTo('foo@example.com'); | |
244 | ```` | |
245 | ||
246 | > {note} `emailOutputTo`、`sendOutputTo` 和 `appendOutputTo` 方法是 `command` 方法才有的,不支持在 `call` 方法上使用。 | |
247 | ||
248 | <a name="task-hooks"></a> | |
249 | ## 任务钩子 | |
250 | ||
251 | 通过 `before` 与 `after` 方法,你可以指定要在调度任务完成之前和之后执行的代码: | |
252 | ||
253 | ```` | |
254 | $schedule->command('emails:send') | |
255 | ->daily() | |
256 | ->before(function () { | |
257 | // 任务就要开始了… | |
258 | }) | |
259 | ->after(function () { | |
260 | // 任务完成… | |
261 | }); | |
262 | ```` | |
263 | ||
264 | #### Ping 网址 | |
265 | ||
266 | 使用 `pingBefore` 与 `thenPing` 方法,调度器可以在任务完成之前或之后自动 ping 给定的 URL。这个方法对于通知外部服务(例如 [Laravel Envoyer](https://envoyer.io))你的调度任务正在开始或已经完成执行很有用: | |
267 | ||
268 | ```` | |
269 | $schedule->command('emails:send') | |
270 | ->daily() | |
271 | ->pingBefore($url) | |
272 | ->thenPing($url); | |
273 | ```` | |
274 | ||
275 | 无论是使用 `pingBefore($url)` 还是 `thenPing($url)` 的功能,都需要 Guzzle HTTP 函数库的支持。你可以使用 `Composer` 将 Guzzle 函数库添加到你的项目中: | |
276 | ||
277 | ```` | |
278 | composer require guzzlehttp/guzzle | |
279 | ```` | |
280 | ||
281 | ## 译者署名 | |
282 | | 用户名 | 头像 | 职能 | 签名 | | |
283 | |---|---|---|---| | |
284 | | [@沈益飞](https://learnku.com/users/13655) | <img class="avatar-66 rm-style" src="https://iocaffcdn.phphub.org/uploads/avatars/13655_1490162781.png?imageView2/1/w/100/h/100"> | 翻译 | [@m809745357](https://github.com/m809745357) at Github | | |
285 | | [@JokerLinly](https://learnku.com/users/5350) | <img class="avatar-66 rm-style" src="https://iocaffcdn.phphub.org/uploads/avatars/5350_1481857380.jpg"> | Review | Stay Hungry. Stay Foolish. | | |
286 | ||
287 | --- | |
288 | ||
289 | > {note} 欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。 | |
290 | > | |
291 | > 转载请注明:本文档由 Laravel China 社区 [laravel-china.org](https://laravel-china.org) 组织翻译,详见 [翻译召集帖](https://learnku.com/laravel/t/5756/laravel-55-document-translation-call-come-and-join-the-translation)。 | |
292 | > | |
293 | > 文档永久地址: https://learnku.com/docs/laravel | |
2 | 294 | |
3 | ||
4 | ||
5 | ||
6 | ||
7 | ||
8 | ||
9 | ||
10 | ||
11 | ||
12 | ||
13 | ||
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ||
20 | ||
21 | ||
22 | ||
23 | ||
24 | ||
25 | ||
26 | ||
27 | ||
28 | ||
29 | ||
30 | ||
31 | ||
32 | ||
33 | ||
34 | ||
35 | ||
36 | ||
37 | ||
38 | ||
39 | ||
40 | ||
41 | ||
42 | ||
43 | ||
44 | ||
45 | ||
46 | ||
47 | ||
48 | ||
49 | ||
50 | ||
51 | ||
52 | ||
53 | ||
54 | ||
55 | ||
56 | ||
57 | ||
58 | ||
59 | ||
60 | ||
61 | ||
62 | ||
63 | ||
64 | ||
65 | ||
66 | ||
67 | ||
68 | ||
69 | ||
70 | ||
71 | ||
72 | ||
73 | ||
74 | ||
75 | ||
76 | ||
77 | ||
78 | ||
79 | ||
80 | ||
81 | ||
82 | ||
83 | ||
84 | ||
85 | ||
86 | ||
87 | ||
88 | ||
89 | ||
90 | ||
91 | ||
92 | ||
93 | ||
94 | ||
95 | ||
96 | ||
97 | ||
98 | ||
99 | ||
100 | ||
101 | ||
102 | ||
103 | ||
104 | ||
105 | ||
106 | ||
107 | ||
108 | ||
109 | ||
110 | ||
111 | ||
112 | ||
113 | ||
114 | ||
115 | ||
116 | ||
117 | ||
118 | ||
119 | ||
120 | ||
121 | ||
122 | ||
123 | ||
124 | ||
125 | ||
126 | ||
127 | ||
128 | ||
129 | ||
130 | ||
131 | ||
132 | ||
133 | ||
134 | ||
135 | ||
136 | ||
137 | ||
138 | ||
139 | ||
140 | ||
141 | ||
142 | ||
143 | ||
144 | ||
145 | ||
146 | ||
147 | ||
148 | ||
149 | ||
150 | ||
151 | ||
152 | ||
153 | ||
154 | ||
155 | ||
156 | ||
157 | ||
158 | ||
159 | ||
160 | ||
161 | ||
162 | ||
163 | ||
164 | ||
165 | ||
166 | ||
167 | ||
168 | ||
169 | ||
170 | ||
171 | ||
172 | ||
173 | ||
174 | ||
175 | ||
176 | ||
177 | ||
178 | ||
179 | ||
180 | ||
181 | ||
182 | ||
183 | ||
184 | ||
185 | ||
186 | ||
187 | ||
188 | ||
189 | ||
190 | ||
191 | ||
192 | ||
193 | ||
194 | ||
195 | ||
196 | ||
197 | ||
198 | ||
199 | ||
200 | ||
201 | ||
202 | ||
203 | ||
204 | ||
205 | ||
206 | ||
207 | ||
208 | ||
209 | ||
210 | ||
211 | ||
212 | ||
213 | ||
214 | ||
215 | ||
216 | ||
217 | ||
218 | ||
219 | ||
220 | ||
221 | ||
222 | ||
223 | ||
224 | ||
225 | ||
226 | ||
227 | ||
228 | ||
229 | ||
230 | ||
231 | ||
232 | ||
233 | ||
234 | ||
235 | ||
236 | ||
237 | ||
238 | ||
239 | ||
240 | ||
241 | ||
242 | ||
243 | ||
244 | ||
245 | ||
246 | ||
247 | ||
248 | ||
249 | ||
250 | ||
251 | ||
252 | ||
253 | ||
254 | ||
255 | ||
256 | ||
257 | ||
258 | ||
259 | ||
260 | ||
261 | ||
262 | ||
263 | ||
264 | ||
265 | ||
266 | ||
267 | ||
268 | ||
269 | ||
270 | ||
271 | ||
272 | ||
273 | ||
274 | ||
275 | ||
276 | ||
277 | ||
278 | ||
279 | ||
280 | ||
281 | ||
282 | ||
283 | ||
284 | ||
285 | ||
286 | ||
287 | ||
288 | ||
289 | ||
290 | ||
291 | ||
292 | ||
293 | ||
294 |