一、定时任务默认是阻塞的
定时任务默认是阻塞的, 即串行执行,若一个服务配置多个定时任务,需要等上一个定时任务执行完,才能执行下一个定时任务
一个定时任务超长了,也不应该阻塞其他定时任务的执行。如一个定时任务每秒执行,而业务执行时间是5秒,那么会隔5秒等待业务执行完毕才会继续下一个定时任务。当前定时任务阻塞后,下一个定时任务得不到执行。
解决方案
- 让业务运行以异步的方式,自己提交到线程池
CompletableFuture.runAsync(()->{
xxxxService.hello();
},executor);
- SpringBoot支持定时任务线程池。默认情况定时任务自动配置的线程数量为1。直接更改配置文件的配置(经常失效)
spring.task.scheduling.pool.size=5
- 让定时任务异步执行
在类上加@EnableAsync
。在定时方法上标上注解@Async
解决:使用异步+定时任务来完成定时任务不阻塞的功能
二、分布式定时任务需要解决的问题
服务有定时任务,当服务部署到多个节点时,每个节点在同一个时间点都会执行相同的定时任务,需要做的是,让同一个时间点,每一个定时任务只在一个节点上执行。
给定时任务加一个分布式锁,再在业务代码里面加上关于幂等的逻辑判断。