Cron表达式揭秘:定时调度一切任务
你需要每晚凌晨3点运行数据库备份。或者每周一早上发送报告。或者每15分钟清除一次缓存。在Linux和Unix服务器上,用于此目的的工具是cron,而告诉cron何时运行任务的方式是cron表达式。
Cron表达式初看之下可能令人望而生畏。0 3 * * *或*/15 9-17 * * 1-5如果你不了解其模式,看起来就像天书。但一旦理解了五个字段,这个语法就出人意料地简单。
五个字段
每个标准cron表达式恰好有五个字段,由空格分隔。每个字段代表一个时间单位:
┌───────────── 分钟 (0-59)
│ ┌───────────── 小时 (0-23)
│ │ ┌───────────── 月中的天 (1-31)
│ │ │ ┌───────────── 月份 (1-12)
│ │ │ │ ┌───────────── 星期几 (0-7, 其中0和7都是周日)
│ │ │ │ │
* * * * *
就是这样。五个字段,从左到右:分钟、小时、月中的天、月份、星期几。
你知道吗? "cron"这个名字来源于希腊词"chronos",意为时间。cron守护进程(后台进程)自1975年以来一直是类Unix操作系统的核心组成部分。
特殊字符
星号(*)——每个值
星号表示该字段的"每个可能值"。
* * * * * = 每天每小时的每一分钟。
逗号(,)——多个值
逗号分隔单独的值。
0 9,12,18 * * * = 在9、12和18点的第0分钟(上午9:00、中午12:00、下午6:00)。
连字符(-)——值范围
连字符定义一个范围。
0 9-17 * * * = 每小时第0分钟,从9点到17点(上午9:00到下午5:00,每小时一次)。
斜杠(/)——步进值
斜杠定义间隔。
*/15 * * * * = 每15分钟(每小时的0、15、30、45分钟)。
0 */2 * * * = 每2小时的第0分钟(午夜、凌晨2点、凌晨4点……)。
读懂Cron表达式:练习
让我们逐步分析常见示例。对于每一个,从左到右读取五个字段。
0 3 * * * — 每天凌晨3:00
| 字段 | 值 | 含义 |
|---|---|---|
| 分钟 | 0 | 第0分钟 |
| 小时 | 3 | 3点(凌晨3点) |
| 月中的天 | * | 每天 |
| 月份 | * | 每月 |
| 星期几 | * | 每个工作日 |
翻译: "每天凌晨3:00。" 夜间备份的经典选择。
*/15 * * * * — 每15分钟
| 字段 | 值 | 含义 |
|---|---|---|
| 分钟 | */15 | 每15分钟 |
| 小时 | * | 每小时 |
| 月中的天 | * | 每天 |
| 月份 | * | 每月 |
| 星期几 | * | 每天 |
翻译: "全天候每15分钟一次。" 常用于健康检查和缓存刷新。
0 9 * * 1-5 — 工作日上午9:00
| 字段 | 值 | 含义 |
|---|---|---|
| 分钟 | 0 | 第0分钟 |
| 小时 | 9 | 9点 |
| 月中的天 | * | 每天 |
| 月份 | * | 每月 |
| 星期几 | 1-5 | 周一至周五 |
翻译: "周一至周五上午9:00。" 非常适合每日工作报告。
0 0 1 * * — 每月1日
| 字段 | 值 | 含义 |
|---|---|---|
| 分钟 | 0 | 第0分钟 |
| 小时 | 0 | 0点(午夜) |
| 月中的天 | 1 | 1号 |
| 月份 | * | 每月 |
| 星期几 | * | 任意星期 |
翻译: "每月1日午夜。" 用于月度报告、账单或清理。
30 8 * * 1 — 每周一上午8:30
| 字段 | 值 | 含义 |
|---|---|---|
| 分钟 | 30 | 第30分钟 |
| 小时 | 8 | 8点 |
| 月中的天 | * | 每天 |
| 月份 | * | 每月 |
| 星期几 | 1 | 周一 |
翻译: "每周一上午8:30。" 非常适合每周团队通知。
编写自己的Cron表达式
以下是系统化的方法:
- 从时间开始。 "每天凌晨3点"或"工作时间内每5分钟"。
- 从左到右填写字段。 先是分钟,然后是小时,接着是月中的天,然后是月份,最后是星期几。
- 用
*表示"每个"。 如果你不关心某个字段,使用*。 - 部署前测试。 始终验证你的表达式生成的调度是否符合预期。
常见模式快速参考
| 调度 | 表达式 |
|---|---|
| 每分钟 | * * * * * |
| 每5分钟 | */5 * * * * |
| 每小时 | 0 * * * * |
| 每天午夜 | 0 0 * * * |
| 每天凌晨3:00 | 0 3 * * * |
| 每周一上午9:00 | 0 9 * * 1 |
| 工作日上午8:30 | 30 8 * * 1-5 |
| 每月1日 | 0 0 1 * * |
| 工作时间每15分钟 | */15 9-17 * * 1-5 |
| 每天两次(上午9点和下午6点) | 0 9,18 * * * |
| 每周日凌晨2:00 | 0 2 * * 0 |
常见错误
忘记小时是0-23
13点是下午1:00,而不是1点。常见错误是写0 1 * * *以为它在下午1:00运行,实际上它在凌晨1:00运行。
星期几的混淆
周日可以是0或7(两者都有效)。周一是1,周六是6。有些人以为周一是0。
月中天与星期几的交互
如果你同时指定了月中的天和星期几(两者都不是*),大多数cron实现会在任一条件满足时运行任务,而不是两个条件同时满足。这让很多人措手不及。
警告 表达式0 9 15 * 1并不意味着"每月15号上午9点,但仅当它是周一时"。它意味着"每月15号上午9点以及每个周一上午9点"。这是意外行为的常见来源。
时区意识
Cron在服务器的本地时区运行。如果你的服务器在UTC,而你在北京(UTC+8),0 9 * * *的cron作业在你当地时间下午5:00运行。始终检查你服务器的时区设置。
提示 部署前测试和可视化你的cron表达式:如何读取和测试Cron表达式。查看下次运行时间并确认调度符合你的意图。
构建和测试你的cron表达式:
免费、即时,无需注册。