定时任务
cron 表达
语法:秒 分 时 日 月 星期 年(年可选,spirng不支持年)
http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html
特殊字符
- “-” :范围, MON-WED表示星期一到星期三
- “,” :列举, MON,WEB表示星期一和星期三
- “*” :任意,指定位置的任意时刻都可以,每月,每天,每周,每年等
- “/” : 步长,0/15(处于分钟段里面) 在0分以后开始每15分钟,3/20 从3分钟以后开始每20分钟。
- “?” : 只能出现在日,星期段里面,表示不指定具体的值,为了防止日和周冲突,在周和日上如果要写通配符使用?
- “L” : 只能出现在日,星期段里面,是Last的缩写,一个月的最后一天,一个星期的最后一天(星期六)
- “W” : 表示工作日,距离给定值最近的工作日
- “#” : 第几个,例如:"6#3"表示每个月的第三个星期五(1=SUN…6=FRI,7=SAT)
cron示例
cron= * * * 1 * ? 不能是 * * * 1 * sun 因为每月的1号不一定是星期天
一般是 日 月 * ? 或者 ? *
Expression | Meaning |
---|---|
0 0 12 * * ? | 每天中午12点触发 |
0 15 10 ? * * | 每天上午10:15触发 |
0 15 10 * * ? | 每天上午10:15触发 |
0 15 10 * * ? * | 每天上午10:15触发 |
0 15 10 * * ? 2005 | 2005年的每天上午10:15触发 |
0 * 14 * * ? | 在每天下午2点到下午2:59期间的每1分钟触发 |
0 0/5 14 * * ? | 在每天下午2点到下午2:55期间的每5分钟触发 |
0 0/5 14,18 * * ? | 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 |
0 0-5 14 * * ? | 在每天下午2点到下午2:05期间的每1分钟触发 |
0 10,44 14 ? 3 WED | 每年三月的星期三的下午2:10和2:44触发 |
0 15 10 ? * MON-FRI | 周一至周五的上午10:15触发 |
0 15 10 15 * ? | 每月15日上午10:15触发 |
0 15 10 L * ? | 每月最后一日的上午10:15触发 |
0 15 10 L-2 * ? | Fire at 10:15am on the 2nd-to-last last day of every month |
0 15 10 ? * 6L | 每月的最后一个星期五上午10:15触发 |
0 15 10 ? * 6L | Fire at 10:15am on the last Friday of every month |
0 15 10 ? * 6L 2002-2005 | 2002年至2005年的每月的最后一个星期五上午10:15触发 |
0 15 10 ? * 6#3 | 每月的第三个星期五上午10:15触发 |
0 0 12 1/5 * ? | Fire at 12pm (noon) every 5 days every month, starting on the first day of the month. |
0 11 11 11 11 ? | Fire every November 11th at 11:11am. |
SringBoot整合
默认springboot就支持定时任务,但是底层使用的框架不是quatz
定时任务:
1、 @EnableScheduling 启用定时任务
2、 @Scheduled开启一个定时任务
3、自动配置类 TaskSchedulingAutoConfiguration
@EnableScheduling
@Component
@Slf4j
public class HelloSchedule {
@Scheduled(cron = "* * * ? * 6")
public void hello() throws InterruptedException {
log.info("hello...");
Thread.sleep(3000);
}
}
分布式定时任务
定时任务问题
1、Spring中6位组成,不允许第7位的年。
2、spring中 周一周周日就是 1-7 MON - SUN
3、定时任务不应该堵塞。默认是堵塞的
1、可以让业务运行以异步的方式,自己提交到线程池
CompletableFuture.runAsync(()->{
xxService.hello();
},executor)
2、支持定时任务线程池TaskSchedulingAutoConfiguration : 设置 TaskSchedulingProperties
spring.task.scheduling.pool.size=10 但是会有bug 有时候不生效
3、让定时任务异步执行
异步执行:
解决:使用异步+定时任务来完成定时任务不堵塞的功能;
扩展-分布式调度
异步任务:springBoot支持
1、@EnableAsync 开启异步任务功能
2、@Async 给希望异步执行的方法上标注
3、自动配置类 TaskExecutionAutoConfiguration
@EnableScheduling // 启用定时任务
@EnableAsync // 启用异步任务支持
@Component
@Slf4j
public class HelloSchedule {
@Async // 这个方法会使用线程池里面的线程来执行
@Scheduled(cron = "* * * ? * 6") // 定时任务表达式
public void hello() throws InterruptedException {
log.info("hello...");
Thread.sleep(3000);
}
}