Quartz Cron、Spring Cron、Linux Crontab 区别和联系
定时任务领域常见的三种 cron 写法:Quartz Cron(Java 调度框架)、Spring Cron(Spring @Scheduled)、Linux Crontab(系统级定时任务)。三者名称相近、格式相似,但字段数量、星期取值、特殊符号和「日 / 周」规则并不完全相同。混用时最容易写错表达式,本文从联系与差异两方面对照说明。
一、三者的联系
- 1. 都使用空格分隔的多段式字符串描述「何时执行」,核心思想一致:在指定时间点或周期触发任务。
- 2. 都支持基础符号
*(任意)、,(枚举)、-(范围)、/(步长)。 - 3. Spring Cron 语法继承自 Quartz,6 段字段顺序与 Quartz 前 6 段一致,扩展符号(
?、L、W、#)也基本相同。 - 4. Quartz 与 Spring 的「日 / 周」采用互斥规则(其中一个须为
?);Linux crontab 则为或(OR)关系。 - 5. 许多「每天 / 每小时 / 每 15 分钟」的业务语义,三种写法都能表达,只是字符串不同,不能直接复制粘贴。
二、字段结构与格式
2.1 字段结构对照
| 类型 | 段数 | 字段顺序 | 典型使用场景 |
|---|---|---|---|
| Quartz Cron | 6~7 段 | 秒 分 时 日 月 周 [年] | Quartz Scheduler、部分分布式任务框架 |
| Spring Cron | 6 段 | 秒 分 时 日 月 周 | Spring / Spring Boot @Scheduled(cron="...") |
| Linux Crontab | 5 段 | 分 时 日 月 周 | crontab -e、系统 cron、Ansible 等 |
2.2 格式示意图
Quartz Cron(6~7 段)
* * * * * * * - - - - - - - | | | | | | +-- 年(可选) | | | | | +------ 周 | | | | +---------- 月 | | | +-------------- 日 | | +------------------ 时 | +---------------------- 分 +-------------------------- 秒
Spring Cron(6 段,无「年」)
* * * * * * - - - - - - | | | | | +------ 周 | | | | +---------- 月 | | | +-------------- 日 | | +------------------ 时 | +---------------------- 分 +-------------------------- 秒
Linux Crontab(5 段,无「秒」、无「年」)
* * * * * - - - - - | | | | +------ 周 | | | +---------- 月 | | +-------------- 日 | +------------------ 时 +---------------------- 分
三、核心差异
3.1 核心差异一览
| 对比项 | Quartz Cron | Spring Cron | Linux Crontab |
|---|---|---|---|
| 是否有「秒」 | 有 | 有 | 无 |
| 是否有「年」 | 可选第 7 段 | 无 | 无 |
| 星期取值 | 1~7 或 SUN~SAT(1=周日) | 0~7 或 SUN~SAT(0 与 7=周日) | 0~7 或 SUN~SAT(0 与 7=周日) |
支持 ? |
是(日 / 周) | 是(日 / 周) | 否 |
支持 L W # |
是 | 是(L/W/# 需 Spring 5.3+) | 否 |
| 「日」与「周」关系 | 互斥,须有一个为 ? |
互斥,须有一个为 ? |
独立;同时指定时为 OR(满足其一即执行) |
| 最小粒度 | 秒级 | 秒级 | 分钟级 |
3.2 同一语义,三种写法
以下表达「同一业务含义」时,字符串不能通用,须分别编写:
| 业务含义 | Quartz / Spring(6 段) | Linux Crontab(5 段) |
|---|---|---|
| 每分钟 | 0 * * * * ? |
* * * * * |
| 每小时整点 | 0 0 * * * ? |
0 * * * * |
| 每天凌晨 | 0 0 0 * * ? |
0 0 * * * |
| 每天上午 9 点 | 0 0 9 * * ? |
0 9 * * * |
| 工作日 9 点 | 0 0 9 ? * MON-FRI |
0 9 * * 1-5 |
| 每 15 分钟 | 0 0/15 * * * ? |
*/15 * * * * |
| 每月 1 号凌晨 | 0 0 0 1 * ? |
0 0 1 * * |
说明:上表 Quartz 列与 Spring 列在以上示例中写法相同;Spring 不支持第 7 段「年」,其余 6 段与 Quartz 一致。Linux 列因缺少「秒」段,整体字段会少一段且顺序不同。
四、星期字段对照
4.1 星期取值对照表
| 类型 | 周日 | 周一 | 周二 | 周三 | 周四 | 周五 | 周六 | 备注 |
|---|---|---|---|---|---|---|---|---|
| Quartz Cron | 1 或 SUN | 2 或 MON | 3 或 TUE | 4 或 WED | 5 或 THU | 6 或 FRI | 7 或 SAT | 1=周日,7=周六 |
| Spring Cron | 0 或 7 或 SUN | 1 或 MON | 2 或 TUE | 3 或 WED | 4 或 THU | 5 或 FRI | 6 或 SAT | 0 与 7 均为周日 |
| Linux Crontab | 0 或 7 或 SUN | 1 或 MON | 2 或 TUE | 3 或 WED | 4 或 THU | 5 或 FRI | 6 或 SAT | 0 与 7 均为周日;支持 SUN~SAT |
4.2 写法示例
示例:「每周一 9 点」
Quartz / Spring:
Spring 也可写:
Linux Crontab:
Quartz / Spring:
0 0 9 ? * MON 或 0 0 9 ? * 2(Quartz 中 2=周一)Spring 也可写:
0 0 9 ? * 1(1=周一)Linux Crontab:
0 9 * * 1(1=周一)或 0 9 * * MON(英文缩写)
五、「日 / 周」规则差异
5.1 Quartz / Spring:互斥
「日」与「周」不能同时指定具体值,其中一个必须为 ?。
正确:
正确:
避免:
0 0 0 15 * ?(每月 15 号)正确:
0 0 0 ? * MON(每周一)避免:
0 0 0 15 * MON(日、周同时指定)
5.2 Linux Crontab:或(OR)关系
「日」与「周」可以同时有值,满足任一条件即执行。
0 0 2 * 1日字段
*:每天;周字段 1:每周一结果:每天凌晨 2 点且每周一凌晨 2 点都会触发(因「每天」已包含周一)
0 0 2 2 1日字段
2:每月 2 号;周字段 1:每周一结果:每月 2 号或每周一凌晨 2 点执行
最佳实践:Linux 中按「星期几」调度时,日期字段用 *;按「几号」调度时,星期字段用 *。
六、特殊字符支持对照
| 字符 | 含义 | Quartz | Spring | Linux |
|---|---|---|---|---|
| * | 任意值 | ✓ | ✓ | ✓ |
| , | 枚举 | ✓ | ✓ | ✓ |
| - | 范围 | ✓ | ✓ | ✓ |
| / | 步长 | ✓ | ✓ | ✓ |
| ? | 不指定(日 / 周) | ✓ | ✓ | — |
| L | 最后(日 / 周) | ✓ | ✓(5.3+) | — |
| W | 最近工作日 | ✓ | ✓(5.3+) | — |
| # | 第 N 个星期 X | ✓ | ✓(5.3+) | — |
七、选型与互转
7.1 如何选型
| 场景 | 推荐 |
|---|---|
| Spring Boot 应用内定时任务 | Spring Cron(@Scheduled) |
| Quartz 集群、持久化、复杂调度 | Quartz Cron(可含「年」段) |
| Linux 服务器脚本、系统运维 | Linux Crontab(5 段) |
| 需要秒级触发 | Quartz / Spring(Linux 最小到分钟) |
| 需要「每月最后一个周五」等高级规则 | Quartz / Spring(L、#);Linux 不支持 |
7.2 互转注意
- 1. Quartz → Spring:去掉第 7 段「年」即可;6 段部分通常可直接使用。
- 2. Spring → Quartz:6 段可直接用于 Quartz;需要按年过滤时再加第 7 段。
- 3. Quartz/Spring → Linux:去掉「秒」段;检查「日 / 周」是否用了
?(Linux 不支持,需改为*或具体值);核对星期数字含义。 - 4. Linux → Quartz/Spring:在最前面补「秒」段(常为
0);「日 / 周」若原为 OR 关系,需改为互斥并加?。 - 5. 含
L、W、#的表达式无法直接用于 Linux crontab。
八、相关工具与教程
| 类型 | 在线生成器 | 详细教程 |
|---|---|---|
| Quartz Cron | Cron 生成器 | Cron 教程 |
| Spring Cron | Spring Cron 生成器 | Spring Cron 教程 |
| Linux Crontab | Crontab 生成器 | Crontab 教程 |
沪公网安备31010502007519号