我懷疑問題是SchedulerFactoryBean的setOverwriteExistingJobs沒有提供足夠的保護。春季石英調度競賽條件
一個節點將被初始化調度,它會決定更換觸發器(斷點org.quartz.impl.jdbcjobstore.SimpleTriggerPersistenceDelegate#deleteExtendedTriggerProperties)
正確的IT執行此方法後,觸發不會在數據庫中,當羣集中的另一個節點嘗試讀取它時(org.quartz.impl.jdbcjobstore.JobStoreSupport#retrieveTrigger),它將失敗,並出現下面的異常。由於這個例外,整個應用程序將無法啓動(不僅僅是調度程序)。
產生的原因:org.quartz.JobPersistenceException:無法檢索 觸發:沒有記錄發現觸發的選擇與關鍵:
日誌可以在https://github.com/apixandru/case-study/tree/master/spring-boot-quartz/logs (例外情況可查詢4日重啓後的服務器,1個節點)
有關演示這個問題去https://github.com/apixandru/case-study/tree/master/spring-boot-quartz
整個項目上找到我們配置調度的方式是這裏
@Bean
JobDetailFactoryBean jobFactoryBean() {
JobDetailFactoryBean bean = new JobDetailFactoryBean();
bean.setDurability(true);
bean.setName("Sampler");
bean.setJobClass(SampleJob.class);
return bean;
}
@Bean
SimpleTriggerFactoryBean triggerFactoryBean(JobDetailFactoryBean jobFactoryBean) {
SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
bean.setName("Sampler Trigger");
bean.setRepeatInterval(20_000);
bean.setJobDetail(jobFactoryBean.getObject());
return bean;
}
@Bean
SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean triggerFactoryBean, DataSource dataSource, Dependency dependency) {
Properties props = new Properties();
props.put("org.quartz.scheduler.instanceId", "AUTO");
props.put("org.quartz.jobStore.isClustered", "true");
SchedulerFactoryBean bean = new SchedulerFactoryBean();
bean.setTriggers(triggerFactoryBean.getObject());
bean.setSchedulerName("Demo Scheduler");
bean.setSchedulerContextAsMap(Collections.singletonMap("dependency", dependency));
bean.setOverwriteExistingJobs(true);
bean.setDataSource(dataSource);
bean.setQuartzProperties(props);
return bean;
}
這種情況發生了很多我們的工作的服務器上,但它的很多困難在本地(獲得可能是由於實際服務器專用,並有更多的動力比我的本地機器?)
要在任何機器上的漏洞,開始在調試模式下一個服務器,並把一個斷點SimpleTriggerPersistenceDelegate.deleteExtendedTriggerProperties,它只是執行後,啓動第二個服務器,你會得到這個異常
無論如何,我設法得到這個錯誤本地以及約4 0重新部署到本地羣集的weblogic服務器。