Cron表达式使用与配置指南

Cron表达式使用与配置指南

目录

什么是Cron表达式

Cron表达式是一种用于配置计划任务的字符串格式,广泛应用于Unix/Linux系统、Java应用、各种调度框架(如Spring Scheduler, Quartz)等场景中,用于定义任务执行的时间规则。

表达式结构

标准格式(6或7字段)

1
2
3
4
5
6
7
8
9
┌───────────── 秒 (0-59) [Quartz扩展]
│ ┌───────────── 分钟 (0-59)
│ │ ┌───────────── 小时 (0-23)
│ │ │ ┌───────────── 日期 (1-31)
│ │ │ │ ┌───────────── 月份 (1-12 或 JAN-DEC)
│ │ │ │ │ ┌───────────── 星期 (0-7 或 SUN-SAT, 0和7都表示周日)
│ │ │ │ │ │ ┌───────────── 年 (可选, 1970-2099) [Quartz扩展]
│ │ │ │ │ │ │
* * * * * * * 命令/任务

注意

  • Unix/Linux cron:使用5字段(分 时 日 月 周)
  • Quartz/Java cron:使用6或7字段(秒 分 时 日 月 周 [年])

各字段详解

字段 必填 允许值 允许的特殊字符
秒(Seconds) 是* 0-59 * , - /
分(Minutes) 0-59 * , - /
小时(Hours) 0-23 * , - /
日期(Day of month) 1-31 * , - / ? L W
月份(Month) 1-12 或 JAN-DEC * , - /
星期(Day of week) 0-7 或 SUN-SAT * , - / ? L #
年(Year) 1970-2099 * , - /

注:秒字段在标准Unix cron中不存在,在Quartz等扩展版本中是必填的

特殊字符说明

基本字符

  • * (星号) - 代表所有可能的值

    • 示例:在分钟字段表示”每分钟”
  • , (逗号) - 指定多个值

    • 示例:0 8,12,18 * * * - 每天8点、12点、18点执行
  • - (连字符) - 指定一个范围

    • 示例:0 9-17 * * * - 每天9点到17点每小时执行一次
  • / (斜杠) - 指定间隔频率

    • 示例:*/5 * * * * - 每5分钟执行一次
    • 示例:0 0 */2 * * - 每2天的0点执行

高级字符(Quartz/Java扩展)

  • ? (问号) - 不指定值(仅用于日期和星期字段)

    • 示例:0 0 0 * * ? - 每天0点执行
  • L (Last) - 最后一天

    • 示例:0 0 0 L * ? - 每月最后一天0点执行
    • 示例:0 0 0 ? * 6L - 每月最后一个周五0点执行
  • W (Weekday) - 最近工作日

    • 示例:0 0 0 15W * ? - 每月15号最近的工作日执行
  • # (井号) - 第几个星期几

    • 示例:0 0 0 ? * 2#3 - 每月第三个周一0点执行

常用示例

Unix/Linux Cron示例(5字段)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
每分钟执行一次
* * * * *

每小时的第30分钟执行
30 * * * *

每天凌晨2点执行
0 2 * * *

每周一上午8点执行
0 8 * * 1

每月1号凌晨0点执行
0 0 1 * *

每15分钟执行一次
*/15 * * * *

工作日上午9点到下午5点,每小时执行
0 9-17 * * 1-5

每天上午8点和晚上8点执行
0 8,20 * * *

Quartz/Java Cron示例(6字段)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
30秒执行一次
*/30 * * * * ?

每天上午10:15执行
0 15 10 ? * *

每月最后一天晚上10点执行
0 0 22 L * ?

每周五下午4点执行
0 0 16 ? * FRI

每月第三个周一上午9点执行
0 0 9 ? * 2#3

每年110点执行
0 0 0 1 1 ? *

工作日每2小时执行一次
0 0 */2 ? * 1-5

不同系统中的差异

Unix/Linux Cron

  • 5个字段:分 时 日 月 周
  • 周字段:0-6 (0=周日)
  • 环境变量:可设置SHELL、PATH等
  • 用户限制:通过/etc/cron.allow、/etc/cron.deny控制
  • 日志:通常记录在/var/log/cron或/var/log/syslog

Quartz Scheduler

  • 6-7个字段:秒 分 时 日 月 周 [年]
  • 周字段:1-7 (1=周日,7=周六) 或 SUN-SAT
  • 支持特殊字符:?, L, W, #
  • 年份支持:1970-2099

Spring @Scheduled

1
2
3
4
5
6
7
8
9
10
11
  支持cron表达式(6字段)
@Scheduled(cron = "0 0 9 * * *")
public void scheduledTask() {
每天9点执行
}

固定延迟
@Scheduled(fixedDelay = 5000)

固定频率
@Scheduled(fixedRate = 5000)

验证与调试工具

1. 在线验证工具

2. 命令行测试(Linux)

1
2
3
4
5
6
7
 测试cron表达式(需要安装cron工具)
crontab -e # 编辑当前用户的crontab
crontab -l # 列出当前用户的cron任务

查看cron日志
tail -f /var/log/cron
tail -f /var/log/syslog | grep CRON

3. 编写测试脚本

1
2
3
4
5
6
!/bin/bash
test_cron.sh
echo "Cron任务执行于: $(date)"
echo "环境变量:"
echo "PATH: $PATH"
echo "用户: $(whoami)"

最佳实践

1. 清晰的注释

1
2
3
4
5
 每天凌晨3点清理临时文件
0 3 * * * /path/to/cleanup.sh

每周一上午8点备份数据库
0 8 * * 1 /path/to/backup.sh

2. 使用完整路径

1
2
3
4
5
 不好
0 * * * * script.sh


0 * * * * /home/user/scripts/script.sh

3. 重定向输出

1
2
3
4
5
 将输出重定向到日志文件
0 * * * * /path/to/script.sh >> /var/log/script.log 2>&1

或丢弃输出
0 * * * * /path/to/script.sh > /dev/null 2>&1

4. 环境变量设置

1
2
3
4
5
6
7
 在crontab顶部设置环境变量
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=admin@example.com

然后定义任务
0 * * * * /path/to/script.sh

5. 避免频繁任务

1
2
3
4
5
 避免:每分钟执行的重型任务
* * * * * /path/to/heavy_task.sh

建议:考虑使用守护进程或调整频率
*/5 * * * * /path/to/optimized_task.sh

6. 错误处理

1
2
 添加错误处理逻辑
0 * * * * /path/to/script.sh || logger "Cron任务失败: $?"

7. 测试新任务

1
2
3
4
5
6
7
8
9
 先手动测试脚本
./script.sh

设置未来几分钟测试
编辑crontab -e,添加测试任务
*/2 * * * * /path/to/script.sh >> /tmp/test.log 2>&1

检查执行结果
tail -f /tmp/test.log

8. 安全性考虑

  • 限制cron访问权限
  • 使用最小权限原则运行任务
  • 定期审查cron任务
  • 避免在cron中使用root权限执行不必要的任务

故障排除

问题 可能原因 解决方案
任务未执行 PATH环境变量不正确 在脚本中设置完整PATH或使用绝对路径
权限错误 脚本没有执行权限 chmod +x script.sh
输出未记录 输出被丢弃或路径错误 检查重定向路径,确保目录存在且有写入权限
时间不正确 系统时区设置错误 检查时区设置:datetimedatectl
邮件通知过多 任务输出频繁 重定向输出到文件或/dev/null

总结

Cron表达式是强大的任务调度工具,但需要正确使用。记住关键点:

  1. 确认系统类型:Unix cron使用5字段,Quartz使用6-7字段
  2. 使用验证工具:在部署前验证表达式
  3. 完整路径:总是使用绝对路径
  4. 日志记录:重要任务要记录输出
  5. 测试:新任务先在测试环境验证

掌握这些知识后,您将能够高效地配置和管理各种定时任务。

1.webp