พื้นหลัง
ในระหว่างการพัฒนาโครงการเรามักจะต้องปฏิบัติงานเป็นระยะ มันสามารถช่วยให้เราบรรลุเป้าหมายได้ดีผ่านงานเวลา
มาเปรียบเทียบเฟรมเวิร์กงานที่ใช้งานอยู่ทั่วไปหลายครั้ง:
ดังที่เห็นได้จากตารางด้านบนเฟรมเวิร์กกำหนดการสปริงมีฟังก์ชั่นที่สมบูรณ์และใช้งานง่ายและใช้งานง่าย กำหนดการฤดูใบไม้ผลิมีคุณสมบัติครบถ้วนสำหรับโครงการขนาดเล็กและขนาดกลาง
1. ตารางการรวม Springboot
1.1 การเพิ่มแพ็คเกจการพึ่งพา Maven
เนื่องจากกำหนดการฤดูใบไม้ผลิรวมอยู่ในโมดูลพื้นฐานสปริง-สตาร์เตอร์สปริงจึงไม่จำเป็นต้องมีการพึ่งพาเพิ่มเติม
<การพึ่งพา> <การพึ่งพา> <roupId> org.springframework.boot </groupId> <ratifactid> Spring-Boot-Starter </Artifactid> </dermentrency> <perndency> <sderctId> org.springframework.boot </groupid> <ratifactid> </predency> </dependencies>
1.2 เริ่มคลาสเพิ่มคำอธิบายประกอบเริ่มต้น
การเพิ่มคำอธิบายประกอบ @enablecheduling ลงในรายการ Springboot หรือคลาสการกำหนดค่าสามารถเปิดใช้งานงานเวลา
@ENABSECHEDULING@SpringBootApplicationPublic คลาส ScheduleApplication {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {springapplication.run (scheduleapplication.class, args);}}1.3. เพิ่มงานที่กำหนดเวลา
เราจะยกตัวอย่างของตารางงานทั้งสามของตารางเวลาฤดูใบไม้ผลิ
1.3.1 cron expressions
คล้ายกับกฎการกำหนดเวลาการแสดงออกของ cron ภายใต้ Linux นิพจน์ cron ประกอบด้วย 6 หรือ 7 ช่องว่างคั่นด้วยฟิลด์เวลาดังแสดงในรูปด้านล่าง:
การแสดงออกทั่วไป:
ใช้เกาลัด:
เพิ่มวิธีการทำงาน () ซึ่งดำเนินการทุก ๆ 10 วินาที
หมายเหตุ: เมื่อเวลาดำเนินการของวิธีการเกินความถี่การตั้งเวลางานตัวกำหนดตารางเวลาจะดำเนินการในรอบถัดไป
ตัวอย่างเช่น: สมมติว่าวิธีการทำงาน () เริ่มดำเนินการในวินาทีที่ 0 และวิธีการจะดำเนินการเป็นเวลา 12 วินาทีจากนั้นในครั้งต่อไปที่วิธีการทำงาน () จะถูกดำเนินการคือวินาทีที่ 20
@ComponentPublic คลาส MyTask {@Scheduled (cron = "0/10 * * * *") งานโมฆะสาธารณะ () {// ลอจิกการดำเนินการงาน}}1.3.2 งานช่วงเวลาคงที่
เวลาดำเนินการงานถัดไปจะคำนวณจากเวลาสิ้นสุดของการดำเนินงานสุดท้ายของวิธีการ และเริ่มดำเนินการตามกฎด้วยกฎนี้เป็นระยะ
ใช้เกาลัด:
เพิ่มวิธีการทำงาน () และดำเนินการทุก ๆ 10 วินาที
ตัวอย่างเช่น: สมมติว่าวิธีการทำงาน () เริ่มดำเนินการในวินาทีที่ 0 และวิธีการจะดำเนินการเป็นเวลา 12 วินาทีจากนั้นในครั้งต่อไปวิธีการทำงาน () จะถูกดำเนินการคือวินาทีที่ 22
@Scheduled (recideDelay = 1000*10) งานโมฆะสาธารณะ () {// ลอจิกงานการดำเนินการ}1.3.3 งานความถี่คงที่
ดำเนินการงานที่ความถี่ที่ระบุและเริ่มดำเนินการตามกำหนดเวลากับกฎนี้เป็นระยะ
ใช้เกาลัด:
เพิ่มวิธีการทำงาน () ซึ่งดำเนินการทุก ๆ 10 วินาที
หมายเหตุ: เมื่อเวลาดำเนินการของวิธีเกินกว่าความถี่ในการตั้งเวลางานผู้กำหนดตารางเวลาจะดำเนินการงานถัดไปทันทีหลังจากที่วิธีการปัจจุบันถูกดำเนินการ
ตัวอย่างเช่น: สมมติว่าวิธีการทำงาน () เริ่มดำเนินการในวินาทีที่ 0 และวิธีการจะดำเนินการเป็นเวลา 12 วินาทีจากนั้นในครั้งต่อไปที่วิธีการทำงาน () จะถูกดำเนินการคือวินาทีที่ 12
@scheduled (recidate = 1000*10) งานโมฆะสาธารณะ () {// งานการดำเนินการตามตรรกะ}}2. กำหนดค่าพูลเธรด Taskscheduler
ในโครงการจริงระบบของเราอาจกำหนดงานเวลาที่หลากหลาย จากนั้นงานเวลาหลายครั้งสามารถดำเนินการได้อย่างอิสระและขนานกัน
โดยการดูที่ org.springframework.scheduling.config.scheduledtaskregistrar ที่มาพบว่าสปริงจะสร้างพูลแบบเธรดเดี่ยวโดยค่าเริ่มต้น สิ่งนี้อาจเป็นอันตรายถึงชีวิตสำหรับการทำงานหลายอย่างของเรา เมื่อมีการดำเนินการหลายงานพร้อมกัน (หรือจำเป็นต้องดำเนินการในเวลาเดียวกัน) ตัวกำหนดเวลางานจะได้สัมผัสกับเวลาดริฟท์และเวลาในการดำเนินงานจะไม่แน่นอน
Void Void ScheduleTasks () {ถ้า (this.taskscheduler == null) {this.localexecutor = executors.newsinglethreathedscheduledexecutor (); this.taskscheduler = ใหม่พร้อมกันพร้อมกัน2.1 พูลเธรดที่กำหนดเอง
เพิ่มคลาสการกำหนดค่าเพื่อใช้งานอินเตอร์เฟส SchedulingConfigurer เขียนเมธอด configureTasks ใหม่และตั้งค่าพูลเธรดที่กำหนดเองผ่าน TaskRegistrar
@ConfigurationPublic คลาส ScheduleConfig ใช้ schedulingConfigurer {@OverridePublic Void ConfigureTasks (ScheduledTaskRegister TaskRegistrar) {TaskRegistrar.setscheduler (Taskexecutor ());}@Bean Executors.newscheduledThreadPool (20);}}3. ปัญหาในการใช้งานจริง
3.1 ปัญหาการเริ่มต้นและการปิดเครื่องในเว็บแอปพลิเคชัน
เรารู้ว่าถั่วที่โหลดหรือเริ่มต้นผ่านฤดูใบไม้ผลิจะถูกขนถ่ายโดยอัตโนมัติ (ถูกทำลาย) เมื่อหยุดบริการ อย่างไรก็ตามเนื่องจากเธรดเป็นระดับ JVM หากผู้ใช้เริ่มเธรดในเว็บแอปพลิเคชันวงจรชีวิตของเธรดนี้จะไม่สอดคล้องกับเว็บแอปพลิเคชัน กล่าวคือแม้ว่าเว็บแอปพลิเคชันจะหยุด แต่เธรดก็ยังไม่สิ้นสุด (ความตาย)
สารละลาย:
1) วัตถุปัจจุบันเริ่มต้นผ่านฤดูใบไม้ผลิ
เมื่อสปริงถอนการติดตั้ง (ทำลาย) อินสแตนซ์วิธีการทำลายของอินสแตนซ์จะถูกเรียก ดำเนินการโดยการใช้วิธีการทำลายการทำลายส่วนต่อประสานแบบ disposableBean ปิดเธรดอย่างแข็งขันในวิธีการทำลาย
@ComponentPublic คลาส MyTask ใช้ disposableBean {@Overridepublic Void Destroy () โยนข้อยกเว้น {// ปิดเธรดหรือเธรดพูล ThreadPoolTaskScheduler Scheduler = (threadpooltaskscheduler) acplicationContext.getBean ("กำหนดตารางเวลา");2) วัตถุปัจจุบันไม่ได้เริ่มต้น (จัดการ) ผ่านฤดูใบไม้ผลิ
จากนั้นเราสามารถเพิ่มผู้ฟังบริบท servlet เพื่อปิดเธรดอย่างแข็งขันเมื่อหยุดบริการ servlet
คลาสสาธารณะ MyTaskListenter ใช้ servletContextListener {@OverridePublic void contextDestroyed (servletContextEvent arg0) {// ปิดเธรดหรือเธรดพูล} // omit ... }3.2 ปัญหาการปรับใช้แบบกระจาย
ในโครงการจริงระบบของเรามักจะถูกนำไปใช้ในกลุ่มการกระจายหรือการกู้คืนภัยพิบัติ จากนั้นงานเวลาอาจมีปัญหาพร้อมกันนั่นคืองานเดียวกันกำลังทำงานบนเซิร์ฟเวอร์หลายตัวในเวลาเดียวกัน
วิธีแก้ปัญหา (ล็อคแบบกระจาย):
1) ล็อคตารางฐานข้อมูล
2) แคชมิดเดิลแวร์
3) ดำเนินการผ่าน Zookeeper
สรุป:
กำหนดการสปริงให้เรามีกรอบงานเวลาที่เรียบง่ายรวดเร็วมีประสิทธิภาพและมีเสถียรภาพ อย่างไรก็ตามมีความจำเป็นที่จะต้องพิจารณาวงจรชีวิตของเธรดและปัญหาการปรับใช้แบบกระจาย
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น