quartz-2.crontab语法

quartz的crontab功能是它的强大之处,它的语法和linux有些类似,但是又有一些不同,例如linux无法精确到秒,而quartz是支持的,本文直接通过例子进行说明。

1. 语法简介

1
[秒] [分] [小时] [日] [月] [星期] [年]

每个位置可以支持设置的值如下:

有几点需要说明

  • 除了年,每个位置是必须的。
  • 每个位置如果无特殊值,可以用*代替,代表每。
  • 除了一些数字,每个位置还允许一些特殊字符。

2. 例子。

下面直接用例子来说明,具体如下:

(1) 每秒执行

1
* * * * * *

啰嗦解释一下就是每个月、每个星期、每天、每小时、每分钟、每秒。所以其实就是每秒。但是如果运行程序就会发现报如下错误, 似乎提示是星期和日是一个矛盾体。

1
2
3
4
5
6
7
8
Exception in thread "main" java.lang.RuntimeException: CronExpression '* * * * * *' is invalid.
at org.quartz.CronScheduleBuilder.cronSchedule(CronScheduleBuilder.java:111)
at com.carlosfu.main.HelloScheduler.main(HelloScheduler.java:28)
Caused by: java.text.ParseException: Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.
at org.quartz.CronExpression.buildExpression(CronExpression.java:511)
at org.quartz.CronExpression.<init>(CronExpression.java:276)
at org.quartz.CronScheduleBuilder.cronSchedule(CronScheduleBuilder.java:107)
... 1 more

因为日和星期是一个矛盾体,所以可以用一个?代替即可,所以下面两个的结果是一样的,都代表每秒。

(a) 每个月的每个星期
1
* * * ? * *
(b) 每个月的每天
1
* * * * * ?
(c)下面两种情况都是错误的
1
2
* * * * ? *
* * * * ? ?

(2) 每分钟执行一次

下面是不是呢?其实仔细想想“分钟”位置0/1和*的效果是一样的

1
* 0/1 * ? * *

也就是说如果想实现每分钟执行一次,要在秒的位置给出具体的值,例如

每分钟的第59秒执行

1
59 0/1 * ? * *

每分钟的第0秒执行

1
0 0/1 * ? * *

有个小技巧,如果需求是只要保证每分钟完成,而不在意在哪秒完成,在大量trigger的情况下,可以对秒做打散操作。

1
2
3
public static String getSlowLogCron() {
return new Random().nextInt(60) + " 0/1 * ? * *";
}

如果

1
0 0/1 * ? * *

具体日志如下

1
2
3
4
5
17:27:00.005 [DefaultQuartzScheduler_Worker-1] INFO com.carlosfu.job.HelloJob - hello quartz!
17:28:00.004 [DefaultQuartzScheduler_Worker-2] INFO com.carlosfu.job.HelloJob - hello quartz!
17:29:00.006 [DefaultQuartzScheduler_Worker-3] INFO com.carlosfu.job.HelloJob - hello quartz!
17:30:00.003 [DefaultQuartzScheduler_Worker-4] INFO com.carlosfu.job.HelloJob - hello quartz!
17:31:00.002 [DefaultQuartzScheduler_Worker-5] INFO com.carlosfu.job.HelloJob - hello quartz!

如果想每5秒执行一次,可以如下:

1
0/5 * * ? * *

如果想每5秒执行一次,但是从每分钟的第20秒到第60秒,可以这么配置

1
20/5 * * ? * *

如果当前的秒小于20,那么就等到执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
now: 2018-01-01 17:35:11
17:35:20.011 [DefaultQuartzScheduler_Worker-1] INFO com.carlosfu.job.HelloJob - hello quartz!
17:35:25.006 [DefaultQuartzScheduler_Worker-2] INFO com.carlosfu.job.HelloJob - hello quartz!
17:35:30.001 [DefaultQuartzScheduler_Worker-3] INFO com.carlosfu.job.HelloJob - hello quartz!
17:35:35.002 [DefaultQuartzScheduler_Worker-4] INFO com.carlosfu.job.HelloJob - hello quartz!
17:35:40.002 [DefaultQuartzScheduler_Worker-5] INFO com.carlosfu.job.HelloJob - hello quartz!
17:35:45.005 [DefaultQuartzScheduler_Worker-6] INFO com.carlosfu.job.HelloJob - hello quartz!
17:35:50.006 [DefaultQuartzScheduler_Worker-7] INFO com.carlosfu.job.HelloJob - hello quartz!
17:35:55.006 [DefaultQuartzScheduler_Worker-8] INFO com.carlosfu.job.HelloJob - hello quartz!
17:36:20.001 [DefaultQuartzScheduler_Worker-9] INFO com.carlosfu.job.HelloJob - hello quartz!
17:36:25.004 [DefaultQuartzScheduler_Worker-10] INFO com.carlosfu.job.HelloJob - hello quartz!
17:36:30.002 [DefaultQuartzScheduler_Worker-1] INFO com.carlosfu.job.HelloJob - hello quartz!
17:36:35.005 [DefaultQuartzScheduler_Worker-2] INFO com.carlosfu.job.HelloJob - hello quartz!

如果当前秒超过20,可以在执行周期内执行。

1
2
3
4
now: 2018-01-01 17:37:24
17:37:25.007 [DefaultQuartzScheduler_Worker-1] INFO com.carlosfu.job.HelloJob - hello quartz!
17:37:30.004 [DefaultQuartzScheduler_Worker-2] INFO com.carlosfu.job.HelloJob - hello quartz!
17:37:35.006 [DefaultQuartzScheduler_Worker-3] INFO com.carlosfu.job.HelloJob - hello quartz!
1
2
3
4
now: 2018-01-01 17:38:38
17:38:40.008 [DefaultQuartzScheduler_Worker-1] INFO com.carlosfu.job.HelloJob - hello quartz!
17:38:45.003 [DefaultQuartzScheduler_Worker-2] INFO com.carlosfu.job.HelloJob - hello quartz!
17:38:50.003 [DefaultQuartzScheduler_Worker-3] INFO com.carlosfu.job.HelloJob - hello quartz!

(3)每天10点20分执行

1
0 20 10 ? * *

(4) 每天下午2点~3点(整点开始,每隔五分钟执行)

1
0 0/5 14 ? * *

(5) 每月的第三周的星期五的10点20分执行

1
0 20 10 ? * 6#3

(6) 每周一到周五的10点20分执行

1
0 20 10 ? * MON-FRI

注意:星期是不分大小写。

3. 其他

特殊字符的解释如下,如果用到的时候可以看下。

也有在线的crontab生成工具:

0和30分执行

1
0/30 * * ? * *

5和35分执行

1
5/30 * * ? * *

1
15/50 * * ? * *
1
2
3
4
5
now: 2018-01-01 18:02:35
18:03:15.006 [DefaultQuartzScheduler_Worker-1] INFO com.carlosfu.job.HelloJob - hello quartz!
18:04:15.005 [DefaultQuartzScheduler_Worker-2] INFO com.carlosfu.job.HelloJob - hello quartz!
18:05:15.005 [DefaultQuartzScheduler_Worker-3] INFO com.carlosfu.job.HelloJob - hello quartz!
18:06:15.003 [DefaultQuartzScheduler_Worker-4] INFO com.carlosfu.job.HelloJob - hello quartz!
1
2
3
4
now: 2018-01-01 17:55:53
17:56:00.010 [DefaultQuartzScheduler_Worker-1] INFO com.carlosfu.job.HelloJob - hello quartz!
17:56:30.004 [DefaultQuartzScheduler_Worker-2] INFO com.carlosfu.job.HelloJob - hello quartz!
17:57:00.001 [DefaultQuartzScheduler_Worker-3] INFO com.carlosfu.job.HelloJob - hello quartz!