(转载)spring boot 项目 同时间定时任务不执行问题


转载:springboot scheduled 解决多定时任务不执行的问题,多线程配置的几种方式

生产上有几个定时任务都是同时间点要执行的,最近发现有的定时任务不执行了,后来经过查资料发现@schedule注解默认是单线程的,如果定时任务比较多或者有的定时任务比较耗时,会影响到其他定时任务的执行。后来查找原因是有个定时任务在sql取数的时候连了几个大表查询,并且相关联查询的字段没有设置索引,导致sql查询超时,影响到了其他定时任务的执行。解决办法是对相关表设置正确的索引,schedule改为多线程执行。关于schedule多线程的配置整理了如下几种配置方式。

第1种:增加配置类

 1 @Configuration
 2 public class ScheduleConfig {
 3     /**
 4      * 修复同一时间无法执行多个定时任务问题。@Scheduled默认是单线程的
 5      */
 6     @Bean
 7     public TaskScheduler taskScheduler() {
 8         ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
 9         //核心线程池数量,方法: 返回可用处理器的Java虚拟机的数量。
10         taskScheduler.setPoolSize(Runtime.getRuntime().availableProcessors() * 2);
11         return taskScheduler;
12     }
13 }

第2种:其实和第一种一样

1 @Configuration
2 public class ScheduleConfig1 implements SchedulingConfigurer {
3     @Override
4     public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
5         scheduledTaskRegistrar.setScheduler(
6                 new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2)
7         );
8     }
9 }

第3种:配置文件添加task配置

1 server:
2   port: 8081
3 spring:
4   application:
5     name: daily-task
6   task:
7     scheduling:
8       pool:
9         size: 8 #配置Scheduled定时任务为多线程

第4种:添加@EnableAsync注解,在相应方法上添加@Async注解

 1 @SpringBootApplication
 2 @EnableScheduling
 3 @EnableAsync
 4 public class TaskApplication {
 5     public static void main(String[] args) {
 6         SpringApplication.run(TaskApplication.class, args);
 7     }
 8 }
 9 
10 @Component
11 public class TestAJob {
12     private static final Logger logger = LoggerFactory.getLogger(TestAJob.class);
13 
14     @Async
15     @Scheduled(cron = "*/2 * * * * ?")
16     public void testA() throws InterruptedException {
17         Thread.sleep(10000);
18         logger.info("testA 执行==============");
19     }
20 }
21 
22 @Component
23 public class TestBJob {
24     private static final Logger logger = LoggerFactory.getLogger(TestBJob.class);
25     
26     @Async
27     @Scheduled(cron = "*/2 * * * * ?")
28     public void testB() {
29         logger.info("testB 执行==============");
30     }
31 }