สภาพการแข่งขัน Spring Quartz Scheduler

สิ่งที่ฉันสงสัยว่าปัญหาคือ setOverwriteExistingJobs ของ SchedulerFactoryBean ไม่ได้ให้การป้องกันที่เพียงพอ

โหนดหนึ่งจะเริ่มต้นตัวกำหนดตารางเวลา และจะตัดสินใจแทนที่ทริกเกอร์ (เบรกพอยต์ org.quartz.impl.jdbcjobstore.SimpleTriggerPersistenceDelegate#deleteExtenstedTriggerProperties )

หลังจากที่ดำเนินการตามวิธีนี้แล้ว ทริกเกอร์จะไม่อยู่ในฐานข้อมูลอีกต่อไป ดังนั้นเมื่อโหนดอื่นในคลัสเตอร์จะพยายามอ่าน (org.quartz.impl.jdbcjobstore.JobStoreSupport#retrieveTrigger) ทริกเกอร์จะล้มเหลวโดยมีข้อยกเว้นด้านล่าง . เนื่องจากข้อยกเว้นนี้ แอปพลิเคชันทั้งหมดจะล้มเหลวในการเริ่มต้น (ไม่ใช่แค่ตัวกำหนดเวลา)

เกิดจาก: org.quartz.JobPersistenceException: ไม่สามารถดึงทริกเกอร์: ไม่พบบันทึกสำหรับการเลือกทริกเกอร์ด้วยคีย์:

สามารถดูบันทึกได้ที่ https://github.com/apixandru/case-study/tree/master/spring-boot-quartz/logs (สามารถพบข้อยกเว้นบนโหนด Server-1 หลังจากรีสตาร์ทครั้งที่ 4)

สำหรับโครงการทั้งหมดที่แสดงให้เห็นถึงปัญหานี้ ให้ไปที่ 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.deleteExtensedTriggerProperties และหลังจากดำเนินการแล้ว ให้เริ่มเซิร์ฟเวอร์ตัวที่สอง แล้วคุณจะได้รับข้อยกเว้นนี้

อย่างไรก็ตาม ฉันจัดการเพื่อรับข้อผิดพลาดนี้ภายในเครื่องเช่นกันหลังจากปรับใช้ใหม่กับเซิร์ฟเวอร์เว็บลอจิกคลัสเตอร์ในเครื่องของฉันประมาณ 40 ครั้ง


person Alexandru    schedule 24.09.2016    source แหล่งที่มา


คำตอบ (1)


ปัญหาคือความจริงที่ว่าตามค่าเริ่มต้นแล้ว ไม่มีการใช้ตัวจัดการธุรกรรม ดังนั้นจึงไม่มีการล็อค

เพื่อแก้ปัญหานี้ จำเป็นต้องเรียกเมธอด setTransactionManager ของ schedulerFactoryBean

person Alexandru    schedule 27.09.2016