定时任务
1. 定时任务概述
任务调度是指系统为了自动完成特定任务,在约定的特定时刻去执行任务的过程。有了任务调度即可解放更多的人力,而是由系统自动去执行任务。
常用业务场景案例:
- 某电商系统需要在每天上午 10 点,下午 3 点,晚上 8 点发放一批优惠券。
- 某银行系统需要在信用卡到期还款日的前三天进行短信提醒。
- 某财务系统需要在每天凌晨 0:10 结算前一天的财务数据,统计汇总。
- 12306 会根据车次的不同,设置某几个时间点进行分批放票。
如何实现任务调度?
- 多线程方式,结合 sleep
- JDK 提供的 API,例如:Timer、ScheduledExecutor
- 框架,例如 Quartz,它是一个功能强大的任务调度框架,可以满足更多更复杂的调度需求,还有一些其他的,比如:XXL-JOB,DolphinScheduler
- SpringTask
2. cron 表达式
在我们使用调度任务技术的时候,特别是调度框架,里面都支持使用日历的方式来设置任务制定的时间、频率等,通常情况下都会使用 cron 表达式来表达。
cron 表达式是一个字符串,用来设置定时规则,由七部分组成,每部分中间用空格隔开,每部分的含义如下表所示:
组成部分 | 含义 | 取值范围 |
---|---|---|
第一部分 | Seconds(秒) | 0-59 |
第二部分 | Minutes(分) | 0-59 |
第三部分 | Hours(时) | 0 - 23 |
第四部分 | Day-of-Month(日) | 1 - 31日 |
第五部分 | Month(月) | 0-11 或 JAN-DEC |
第六部分 | Day-of-Week(星期) | 1 - 7(1 表示星期日)或 SUN - SAT |
第七部分 | Year(年)可选 | 1970 - 2099 |
另外,cron 表达式还可以包含一些特殊符号来设置更加灵活的定时规则,如下表所示:
符号 | 含义 |
---|---|
? |
表示不确定的值。为了避免两个子表达式冲突,需要将另外一个的值设为 "?" |
* |
代表所有可能的值 |
, |
设置多个值 |
- |
设置取值范围 |
/ |
设置频率或间隔 |
L |
用于每月,或每周,表示每月的最后一天,或每个月的最后星期几 |
W |
表示离给定日期最近的工作日 |
# |
表示该月第几个周 X |
例子:
cron表达式 | 含义 |
---|---|
*/5 * * * * ? |
每隔 5 秒运行一次任务 |
0 0 23 * * ? |
每天 23 点运行一次任务 |
0 0 1 1 * ? |
每月 1 号凌晨 1 点运行一次任务 |
0 0 23 L * ? |
每月最后一天 23 点运行一次任务 |
0 26,29,33 * * * ? |
在 26 分、29 分、33 分运行一次任务 |
0 0/30 9-17 * * ? |
朝九晚五工作时间内每半小时运行一次任务 |
0 15 10 ? * 6#3 |
每月的第三个星期五上午 10:15 运行一次任务 |
3. SpringTask 入门
-
导入 maven 依赖 spring-context
目前项目中只要导入了 springboot 相关依赖会自动导入,这一步无需操作
-
自定义定时任务类
@Component @Slf4j public class MyTask {@Scheduled(cron = "0/5 * * * * ?")public void executeTask() { log.info("{}", LocalDateTime.now()); } }
-
启动类添加注解
@EnableScheduling
-
启动项目,测试效果