spring task 是spring boot 3.0以上自带的task,
在Spring应用中,直接使用@Scheduled注解即可,但对于集群项目比较麻烦,需要避免集群环境下任务被多次调用的情况,而且不能动态维护,任务启动以后不能修改、暂停等。
一、Application
增加@EnableScheduling注解
二、定时执行
package com.example.demo;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@EnableScheduling
public class taskTest {
//使用cron属性可按照指定时间执行,本例指的是每1分钟执行一次;
@Scheduled(cron = "0 0/1 * * * ?")
public void test1() {
System.out.println("[" + Thread.currentThread().getName() + "]" + "-----------test1-----------");
}
//使用cron属性可按照指定时间执行,本例指的是每1分钟执行一次;
@Scheduled(cron = "0 0/1 * * * ?")
public void test2() {
System.out.println("[" + Thread.currentThread().getName() + "]" + "-----------test2-----------");
}
}
三、cron表达式
注:下面内容主要参考Quartz的文档,对于Spring Task基本都适用。
cron表达式是由7个域组成的字符串,它们描述了任务计划的各个细节,这些域用空格分隔,每个域代表的含义如下:
- Seconds(秒)
- Minutes(分)
- Hours(时)
- Day-of-Month(日)
- Month(月)
- Day-of-Week(星期)
- Year(可选字段)(年)
示例:0 0 10 ? * WED
表示每个星期三的10:00:00
表达式 | {秒} | {分} | {时} | {日} | {月} | {周} | {年}(可选) |
允许值 | 0~59 | 0~59 | 0~23 | 1~31 | 1~12 JAN~DEC | 1~7 SUN~SAT | 1970~2099 |
特殊值 |
|
|
|
|
|
|
|
说明:下面描述中,XX域则表示cron表达式相应的位置,如秒
域表示cron中第1个值,日
域则表示cron表达式第4个值等等。
- 月份简称:
JAN
,FEB
,MAR
,APR
,MAY
,JUN
,JUL
,AUG
,SEP
,OCT
,NOV
和DEC
。 - 星期简称:
SUN
,MON
,TUE
,WED
,THU
,FRI
和SAT
。其中,1表示SUN
。 -
,
:用来分割在域上指定的多个值。如:MON,WED,FRI
在星期域里表示星期一、星期三、星期五
。 -
/
:用于指定增量值。如分钟上使用0/15
,表示从零开始,每隔15分钟,等价于0,15,30,45
。如分钟上使用3/15
,表示从第3分钟开始,每隔15分钟,等价于3,18,33,48
,x/y
中x表示开始值,y表示步长。 -
*
:表示匹配该域的任意值。如秒上使用*表示每秒触发一次。 -
-
:表示指定一个范围,如分钟域上10-13
,表示10分、11分、12分、13分
。 -
?
:表示不关心的域,可用于日
和周
两个域上,主要用来解决日
和周
两个域的冲突。和*
类似,区别在于*
关心域,只是域的值可以任意,?
则表示对该域不关心,不需要看该域的内容,直接忽略。 L
:表示最后,是单词last
的首字母,可用于日
和周
两个域上,用在日
和周
上含义不同:
-
日
域上表示月份中日期的最后一天,如一月的第31天、非闰年二月的第28天。 -
周
域上单独使用仅表示7
或SAT
,即仅表示周六。但是如果跟在其他值后,如6L
或FRIL
则表示该月中最后一个星期五。 -
L
还可以指定偏移量,如日
域指定L-3
,表示该月倒数第3天。当使用L
时其值尽量不要指定列表或范围,以免令人困惑。
-
W
:用于日
域,表示距离指定日最近的星期几(周一至周五中的一个),如:日
域上值为15W
则表示距离本月第15日最近的工作日。 -
#
:用于周
域,表示该月的第n个星期几。如:周
域值为6#3
或FRI#3
表示该月的第3个星期五。
四、@Scheduled(cron = "0 0 1 * * *")常用表达式示例
-
0 0 10,14,16 * * ?
每天上午10点、下午两点、下午4点整触发 -
0 0/30 9-17 * * ?
每天朝九晚五内每隔半小时触发 -
0 15 10 ? * MON-FRI
周一至周五的上午10:15触发 -
0 0/5 * * * ?
每5分钟触发 -
10 0/5 * * * ?
每隔5分钟的第10秒触发(即10:00:10、10:05:10、10:10:10等) -
30 * * * * ?
每半分钟触发 -
30 10 * * * ?
每小时的10分30秒触发 -
30 10 1 * * ?
每天1点10分30秒触发 -
30 10 1 20 * ?
每月20号1点10分30秒触发 -
30 10 1 20 10 ? *
每年10月20号1点10分30秒触发 -
30 10 1 20 10 ? 2011
2011年10月20号1点10分30秒触发 -
30 10 1 ? 10 * 2011
2011年10月每天1点10分30秒触发 -
30 10 1 ? 10 SUN 2011
2011年10月每周日1点10分30秒触发 -
15,30,45 * * * * ?
每15秒,30秒,45秒时触发 -
15-45 * * * * ?
15到45秒内,每秒都触发 -
15/5 * * * * ?
每分钟的每15秒开始触发,每隔5秒触发一次 -
15-30/5 * * * * ?
每分钟的15秒到30秒之间开始触发,每隔5秒触发一次 -
0 0/3 * * * ?
每小时的第0分0秒开始,每三分钟触发一次 -
0 15 10 ? * MON-FRI
星期一到星期五的10点15分0秒触发 -
0 15 10 L * ?
每个月最后一天的10点15分0秒触发 -
0 15 10 LW * ?
每个月最后一个工作日的10点15分0秒触发 -
0 15 10 ? * 5L
每个月最后一个星期四的10点15分0秒触发 -
0 15 10 ? * 5#3
每个月第三周的星期四的10点15分0秒触发
五、Spring Boot 的 application.properties
中相关的配置说明
# 是否允许核心线程超时。这样可以动态增加和缩小线程池
spring.task.execution.pool.allow-core-thread-timeout=true
# 核心线程池大小 默认 8
spring.task.execution.pool.core-size=8
# 线程空闲等待时间 默认 60s
spring.task.execution.pool.keep-alive=60s
# 线程池最大数 根据任务定制
spring.task.execution.pool.max-size=10
# 线程池 队列容量大小
spring.task.execution.pool.queue-capacity=50
# 线程池关闭时等待所有任务完成
spring.task.execution.shutdown.await-termination=true
# 执行线程关闭前最大等待时间,确保最后一定关闭
spring.task.execution.shutdown.await-termination-period=50
# 线程名称前缀
spring.task.execution.thread-name-prefix=task-