คำนำ
เพื่อให้แน่ใจว่ามีความพร้อมใช้งานสูงและมีการพร้อมกันของแอปพลิเคชันสูงหลายโหนดจะถูกปรับใช้โดยทั่วไป สำหรับงานกำหนดเวลาหากแต่ละโหนดทำงานตามกำหนดเวลาของตัวเองมันจะใช้ทรัพยากรระบบในมือข้างหนึ่ง
ในทางกลับกันงานบางอย่างจะดำเนินการหลายครั้งซึ่งอาจทำให้เกิดปัญหาตรรกะของแอปพลิเคชันดังนั้นจึงจำเป็นต้องมีระบบการจัดตารางเวลาแบบกระจายเพื่อประสานงานแต่ละโหนดเพื่อปฏิบัติงานตามเวลา
ฤดูใบไม้ผลิรวมควอตซ์
ควอตซ์เป็นระบบจัดตารางงานที่ครบกำหนด ฤดูใบไม้ผลิเข้ากันได้กับควอตซ์เพื่อการพัฒนาที่ง่าย มาดูวิธีการรวมกัน:
1. ไฟล์การพึ่งพา
<การพึ่งพา> <การพึ่งพา> <roupId> org.springframework </groupId> <ratifactId> Spring-Core </ArtifactId> <Sersion> 4.3.5.Release </Side> <Sersion> 4.3.5.Release </เวอร์ชัน> </การพึ่งพา> <การพึ่งพา> <roupId> org.springframework </groupId> <ArtIfactId> Spring-Tx </artifactid> <version> 4.3.5.Release </เวอร์ชัน> <Sersion> 4.3.5.Release </เวอร์ชัน> </การพึ่งพา> <การพึ่งพา> <roupId> org.quartz-Scheduler </groupId> <ArtIfactId> quartz </artifactid> <version> 2.2.3 </เวอร์ชัน> </การพึ่งพา <Sersion> 5.1.29 </Servive> </predency> </pendencies>
ห้องพักหลักคือห้องสมุดที่เกี่ยวข้องกับฤดูใบไม้ผลิห้องสมุดควอตซ์และไลบรารีไดรเวอร์ MySQL หมายเหตุ: การกำหนดเวลาแบบกระจายต้องใช้ฐานข้อมูลและเลือก MySQL ที่นี่
2. กำหนดค่างาน
มีสองวิธีในการกำหนดค่างานคือ: MethodInvokingJobDetailFactoryBean และ JobDetailFactoryBean
2.1methodinvokingjobdetailfactorybean
เมื่อคุณต้องการเรียกวิธีการของถั่วที่เฉพาะเจาะจงการกำหนดค่าเฉพาะมีดังนี้:
<bean id = "firsttask"> <property name = "targetObject" ref = "FirstService" /> <property name = "targetMethod" value = "service" /> </ea>
2.2JobDetailFactoryBean
วิธีนี้มีความยืดหยุ่นมากขึ้นและสามารถตั้งค่าพารามิเตอร์ที่ผ่านได้ดังนี้:
<bean id = "firsttask"> <property name = "jobclass" value = "zh.maven.squartz.task.firsttask"/> <property name = "jobDatamap"> <map> <entry key = "FirstService" value-ref = "FirstService
คลาสงานที่กำหนดโดย JobClass สืบทอด Quartzjobbean และใช้วิธีการ ExecuteInternal; JobDatamap ใช้เพื่อส่งข้อมูลไปยังงาน
3. กำหนดค่าทริกเกอร์ที่ใช้สำหรับการตั้งเวลา
นอกจากนี้ยังมีสองประเภททริกเกอร์: SimpleTriggerFactoryBean และ CrontriggerFactoryBean
มุ่งเน้นไปที่ CrontriggerFactoryBean ประเภทนี้มีความยืดหยุ่นมากขึ้นดังนี้:
<bean id = "firstcrontrigger"> <property name = "jobDetail" ref = "firsttask" /> <property name = "cronexpression" value = "0/5 * *? * *" /> < /bean>
JobDetail ระบุงานที่กำหนดค่าไว้ในขั้นตอนที่ 2 และ Cronexpression ได้รับการกำหนดค่าให้ดำเนินการงานทุก ๆ 5 วินาที
4. กำหนดค่า SchedulerFactoryBean ของตัวกำหนดตารางเวลาควอตซ์
นอกจากนี้ยังมีสองวิธี: หน่วยความจำ Ramjobstore และฐานข้อมูล
4.1 หน่วยความจำ ramjobstore
ข้อมูลที่เกี่ยวข้องกับงานจะถูกเก็บไว้ในหน่วยความจำและแต่ละโหนดจะเก็บของตัวเองแยกกันและกำหนดค่าดังต่อไปนี้:
<ebean> <property name = "ทริกเกอร์"> <list> <ref bean = "FirstCrontrigger"/> </list> </porepore> </epean>
4.2 วิธีการฐานข้อมูล
ข้อมูลที่เกี่ยวข้องของงานจะถูกเก็บไว้ในฐานข้อมูล โหนดทั้งหมดแชร์ฐานข้อมูล แต่ละโหนดสื่อสารผ่านฐานข้อมูลเพื่อให้แน่ใจว่างานจะถูกดำเนินการเฉพาะในโหนดเดียวในเวลาเดียวกัน
หากโหนดล้มเหลวงานจะถูกกำหนดให้กับโหนดอื่นเพื่อดำเนินการ การกำหนดค่าเฉพาะมีดังนี้:
<bean id = "dataSource" destroy-method = "close"> <property name = "driverclass" value = "com.mysql.jdbc.driver" /> <property name = "jdbcurl" value = "jdbc: mysql: // localhost: 3306 /quartz" </ebean> <Bean> <property name = "dataSource" ref = "dataSource"/> <property name = "configlocation" value = "classpath: quartz.properties"/> <property name = "Triggers"> <list> <ref bean = "FirstCrontrigger"
DataSource ใช้เพื่อกำหนดค่าแหล่งข้อมูลและข้อมูลที่เกี่ยวข้องกับตารางข้อมูล คุณสามารถดาวน์โหลดแพ็คเกจ GZ จากเว็บไซต์ทางการ ไฟล์ SQL อยู่ภายใต้ PATH: DOCS/DBTABLES ซึ่งให้ไฟล์ SQL สำหรับฐานข้อมูลกระแสหลัก
ไฟล์ quartz.properties ที่กำหนดค่าในการกำหนดค่าอยู่ในแพ็คเกจ org.quartz ของ quartz.jar ซึ่งให้ข้อมูลเริ่มต้นบางอย่างเช่น org.quartz.jobstore.class
org.quartz.jobstore.class: org.quartz.simpl.ramjobstore
ที่นี่คุณต้องคัดลอก quartz.properties และทำการแก้ไขบางอย่าง การปรับเปลี่ยนเฉพาะมีดังนี้:
org.quartz.scheduler.instanceId: autoorg.quartz.jobstore.class: org.quartz.impl.jdbcjobstore.jobstoretxorg.quartz.jobstore.isclustered: trueorg.quartz.jobstore.clusterveck
5. หมวดหมู่ที่เกี่ยวข้อง
ชั้นเรียนสาธารณะ FirstTask ขยาย Quartzjobbean {ส่วนตัว FirstService FirstService; @Override void protected executeInternal (jobExecutionContEntext บริบท) พ่น JOBExecutionException {FirstService.Service (); } โมฆะสาธารณะ setFirstService (FirstService FirstService) {this.firstService = FirstService; -FirstTask สืบทอด Quartzjobbean ใช้วิธีการ ExecuteInternal และเรียก FirstService
ชั้นเรียนสาธารณะ FirstService ใช้ serializable {private static final final long serialversionuid = 1l; บริการโมฆะสาธารณะ () {System.out.println (ใหม่ SimpledateFormat ("Yyymmdd HH: MM: SS") รูปแบบ (วันที่ใหม่ ()) + "--- เริ่มต้น FirstService"); ลอง {thread.sleep (2000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println (ใหม่ SimpledateFormat ("yyymmdd hh: mm: ss"). รูปแบบ (วันที่ใหม่ ()) + "--- สิ้นสุด FirstService"); -FirstService จำเป็นต้องจัดให้มีอินเทอร์เฟซอนุกรมเนื่องจากจำเป็นต้องบันทึกไว้ในฐานข้อมูล
แอพคลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {AbstractapplicationContext Context = ใหม่ classPathxMlApplicationContext ("quartz.xml"); -คลาสหลักใช้ในการโหลดไฟล์การกำหนดค่าควอตซ์
ทดสอบการจัดตารางการกระจาย
1. เริ่มแอปสองครั้งในเวลาเดียวกันและสังเกตบันทึก:
20180405 14:48:10 --- เริ่มต้น FirstService
20180405 14:48:12 ---- สิ้นสุด FirstService
20180405 14:48:15 --- เริ่มต้น FirstService
20180405 14:48:17 ---- สิ้นสุด FirstService
ในหมู่พวกเขา A1 มีเอาต์พุตบันทึก แต่ A2 ไม่ได้; เมื่อ A1 หยุดลง A2 จะมีเอาต์พุตบันทึก
2. เพิ่มงานใหม่และสร้างงานใหม่: SecondTask และ SecondService ตามลำดับ เพิ่มไฟล์การกำหนดค่าที่เกี่ยวข้องในเวลาเดียวกัน เริ่มแอปสองครั้งและสังเกตบันทึก:
บันทึก A1 มีดังนี้:
20180405 15:03:15 --- เริ่มต้น FirstService
20180405 15:03:15 --- เริ่มบริการวินาที
20180405 15:03:17 ---- สิ้นสุด FirstService
20180405 15:03:17 --- สิ้นสุดวินาทีบริการ
20180405 15:03:20 --- เริ่มต้น FirstService
20180405 15:03:22 ---- สิ้นสุด FirstService
20180405 15:03:25 --- เริ่มต้น FirstService
20180405 15:03:27 ---- สิ้นสุด FirstService
บันทึก A2 มีดังนี้:
20180405 15:03:20 --- เริ่มต้นวินาที
20180405 15:03:22 --- สิ้นสุดวินาทีบริการ
20180405 15:03:25 --- เริ่มบริการวินาที
20180405 15:03:27 --- สิ้นสุดวินาทีบริการ
จะพบได้ว่าทั้ง A1 และ A2 มีงานดำเนินการ แต่งานเดียวกันจะถูกดำเนินการในโหนดเดียวในเวลาเดียวกันและเป็นไปได้ที่จะได้รับมอบหมายให้โหนดอื่น ๆ หลังจากการดำเนินการเสร็จสมบูรณ์
3. หากเวลาช่วงเวลาน้อยกว่าเวลาดำเนินการงานตัวอย่างเช่นที่นี่จะเปลี่ยนเป็น Sleep (6000)
บันทึก A1 มีดังนี้:
20180405 15:14:40 --- เริ่มต้น FirstService
20180405 15:14:45 --- เริ่มต้น FirstService
20180405 15:14:46 ---- สิ้นสุด FirstService
20180405 15:14:50 --- เริ่มต้น FirstService
20180405 15:14:50 --- เริ่มต้นวินาที
20180405 15:14:51 --- สิ้นสุด FirstService
บันทึก A2 มีดังนี้:
20180405 15:14:40 --- เริ่มบริการวินาที
20180405 15:14:45 --- เริ่มบริการวินาที
20180405 15:14:46 --- สิ้นสุดวินาทีบริการ
20180405 15:14:51 --- สิ้นสุดวินาทีบริการ
ช่วงเวลาคือ 5 วินาทีในขณะที่การดำเนินงานใช้เวลา 6 วินาที การสังเกตบันทึกคุณจะพบว่างานยังไม่สิ้นสุดและงานใหม่ได้เริ่มขึ้นแล้ว สถานการณ์นี้อาจทำให้เกิดปัญหาเชิงตรรกะในแอปพลิเคชันซึ่งเป็นคำถามที่ว่างานสามารถสนับสนุนอนุกรมได้หรือไม่
4. @disallowconcurrentexecution คำอธิบายประกอบการทำให้มั่นใจได้ถึงการทำให้เป็นอนุกรมของงาน
เพิ่ม @disallowconcurrentexecution คำอธิบายประกอบบน FirstTask และ SecondTask ตามลำดับและผลการบันทึกมีดังนี้:
บันทึก A1 มีดังนี้:
20180405 15:32:45 --- เริ่มต้น FirstService
20180405 15:32:51 --- สิ้นสุด FirstService
20180405 15:32:51 --- เริ่มต้น FirstService
20180405 15:32:51 --- เริ่มต้นวินาที
20180405 15:32:57 ---- สิ้นสุด FirstService
20180405 15:32:57 --- สิ้นสุดวินาทีบริการ
20180405 15:32:57 --- เริ่มต้น FirstService
20180405 15:32:57 --- เริ่มบริการวินาที
บันทึก A2 มีดังนี้:
20180405 15:32:45 --- เริ่มบริการวินาที
20180405 15:32:51 --- สิ้นสุดวินาทีบริการ
การสังเกตบันทึกคุณจะพบว่างานจะเริ่มงานใหม่หลังจากสิ้นสุดและตระหนักถึงการทำให้เป็นอนุกรมของงาน;
สรุป
บทความนี้มีจุดมุ่งหมายที่จะมีความเข้าใจที่เข้าใจง่ายเกี่ยวกับการจัดตารางการกระจาย Spring+Quartz และแก้ปัญหาผ่านการใช้งานจริง แน่นอนว่าอาจมีคำถามมากมายเช่นกำหนดเวลาจะเกิดอะไรขึ้นหากฐานข้อมูลถูกแขวน ฯลฯ และจำเป็นต้องมีความเข้าใจในเชิงลึกมากขึ้น
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น