初始問題:
采用Spring-Task配置定時任務,任務執行兩次,該問題在Eclipse調試環境上不出現
分析問題:
第一步:開始懷疑業務邏輯,通過排查和定位排除業務原因(通過日志可以查看多次執行)
1 @Component("collection.car") 2 public class CollectionCarsJob { 3 private static Logger logger = LoggerFactory.getLogger(CollectionCarsJob.class); 4 @Scheduled(cron = "0 0 1 * * *") 5 public void packDaysCollectionData() { 6 ... 7 logger.info("Insert stat data for collections of cars. {}", date);
第二步:懷疑定時任務Bug,導致定時任務被注冊多次(通過日志發現初始化位置被多次調用)
1 @EnableScheduling 2 public class WebAppConfig extends WebMvcConfigurerAdapter implements SchedulingConfigurer{ 3 private static Logger logger = LoggerFactory.getLogger(WebAppConfig.class); 4 //TaskScheduler configuration 5 @Override 6 public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 7 logger.info("Configure task registor: {}", taskRegistrar); 8 taskRegistrar.setScheduler(taskExecutor()); 9 } 10 11 @Bean(destroyMethod="shutdown") 12 public Executor taskExecutor() { 13 return Executors.newScheduledThreadPool(4); 14 }
在網上查找,發現很多由於配置重復導致,由於本項目采用完全注解的配置方式,所以不存在多次配置
在查看啟動日志的時候,發現除了任務被初始化兩次外,spring應用也被初始化兩次
第三步:tomcat配置導致容器被初始化兩次
由於app直接放在tomcat的webapp下,並且通過根路徑訪問,配置如下
1 <Context path="" docBase="tower-webmvc" debug="0" reloadable="true" crossContext="true"/>
查找類似問題處理方式:
方法1:不配置根路徑訪問
方法2:將路徑已出webapp目錄,在docBase中指定路徑(可以是相對於webapp的路徑,或者絕對路徑)【推薦】
方法3:替換ROOT目錄【推薦】
方法4:在conf/Catalina/localhost生成ROOT.xml,並加入如下內容:
1 <?xml version='1.0' encoding='utf-8'?> 2 <Context docBase="xxx" path="" reloadable="true" />