1. مبدأ التنفيذ الأساسي لجدولة مهمة الكوارتز
الكوارتز هو مشروع مفتوح المصدر في مجال جدولة المهام بواسطة OpenSymphony ، والذي يعتمد تمامًا على تنفيذ Java. كإطار جدولة مفتوح المصدر ممتاز ، لدى الكوارتز الميزات التالية:
(1) يمكن أن تلبي وظائف الجدولة القوية ، مثل دعم مجموعة متنوعة من طرق الجدولة ، الاحتياجات التقليدية والخاصة المختلفة ؛
(2) طرق التطبيق المرنة ، مثل دعم مجموعات متعددة من المهام والجدولة ، ودعم طرق تخزين متعددة لجدولة بيانات الجدولة ؛
(3) قدرات الموزعة والتجميع ، قامت Terracotta بتحسين وظائفها الأصلية بعد الاستحواذ. ستضيف هذه المقالة إلى هذا الجزء.
1.1 العناصر الأساسية الكوارتز
العناصر الأساسية لجدولة المهام الكوارتز هي: جدولة جدولة المهام ، وفعالية الزناد ، ومهام الوظائف. عندما يكون Trigger و Job بيانات تعريف لجدولة المهام ، والمجدول هو وحدة التحكم التي تؤدي بالفعل الجدولة.
Trigger هو عنصر يستخدم لتحديد وقت الجدولة ، أي وفقًا لقواعد الوقت التي يتم تنفيذ المهمة. هناك أربعة أنواع من المشغلات في الكوارتز: SimpleTrigger ، Crontirgger ، DateIntervaltrigger ، و nthincludeddayTrigger. يمكن لهذه المشغلات الأربعة تلبية معظم احتياجات تطبيقات المؤسسات.
يتم استخدام الوظيفة لتمثيل المهام المجدولة. هناك أساسا نوعان من الوظائف: عديمة الجنسية ودولة. لنفس المشغل ، لا يمكن تنفيذ الوظائف الحكومية بالتوازي. فقط بعد تنفيذ المهمة التي تم تشغيلها الأخير ، يمكن تشغيل التنفيذ التالي. لدى Job سمتان رئيسيتان: المتقلبين والمتانة ، حيث يعني المتقلبة ما إذا كانت المهمة تستمر في تخزين قاعدة البيانات ، في حين أن المتانة تعني ما إذا كانت المهمة قد تم الاحتفاظ بها عندما لا تكون هناك ارتباط بالشغل. كلاهما مستمر أو الحفاظ عليه عندما تكون القيمة صحيحة. يمكن أن ترتبط الوظيفة بمشغلات متعددة ، ولكن يمكن للمشغل أن يربط وظيفة واحدة فقط.
يتم إنشاء Scheduler بواسطة Scheduler Factory: DirectSchedulerFactory أو StdSchedulerFactory. يتم استخدام المصنع الثاني ، stdschedulerfactory ، بشكل متكرر لأن DirectSchedulerFactory غير مريح بما يكفي للاستخدام ، ويلزم العديد من إعدادات الترميز اليدوي التفصيلي. هناك ثلاثة أنواع رئيسية من الجدولة: Remotembeanscheduler ، و quotescheduler و stdscheduler.
يوضح الشكل 1.1 العلاقة بين العناصر الأساسية للكوارتز:
الشكل 1.1 مخطط علاقة العنصر الأساسي
1.2 عرض خيط الكوارتز
في الكوارتز ، هناك نوعان من مؤشرات الترابط ، ومواضيع جدولة جدولة ومواضيع تنفيذ المهام ، حيث تستخدم مؤشرات ترابط تنفيذ المهمة عادة تجمع مؤشرات الترابط للحفاظ على مجموعة من مؤشرات الترابط.
الشكل 1.2 عرض مؤشر ترابط الكوارتز
هناك نوعان من المواضيع الرئيسية للجدولة: مؤشرات الترابط التي تؤدي الجدولة العادية والمواضيع التي تنفذ MisfiredTrigger. استطلاعات رسائل الإرسال العادية جميع المشغلات المخزنة. إذا كان هناك مشغل يحتاج إلى تشغيل ، أي أن وقت الزناد التالي الذي تم الوصول إليه ، فإنه يحصل على مؤشر ترابط خمول من مجموعة مؤشرات ترابط تنفيذ المهمة لتنفيذ المهمة المرتبطة بالمشغل. يقوم خيط الاختلاف بمسح جميع المشغلات لمعرفة ما إذا كان هناك مجموعة مختلطة. إذا كان الأمر كذلك ، يتم التعامل معها بشكل منفصل وفقًا لسياسة الاختلال (النار الآن أو انتظر الحريق التالي).
1.3 تخزين بيانات وظيفة الكوارتز
يجب تخزين المشغلات والوظائف في الكوارتز قبل استخدامها. هناك طريقتان للتخزين في الكوارتز: Ramjobstore و Jobstoresupport ، حيث تقوم شركة Ramjobstore بمتاجر المشغلات والوظائف في الذاكرة ، في حين أن مخازن Jobstoresupport المشغلات والوظائف في قاعدة البيانات بناءً على JDBC. Ramjobstore وصول سريع للغاية ، ولكن نظرًا لأن جميع البيانات ستضيع بعد إيقاف النظام ، يجب استخدام Jobstoresupport في تطبيقات المجموعة.
2. مبدأ الكتلة الكوارتز 2.1 العمارة الكتلة الكوارتز
كل عقدة في مجموعة الكوارتز هي تطبيق كوارتز مستقل ، والذي بدوره يدير العقد الأخرى. هذا يعني أنه يجب عليك البدء أو إيقاف كل عقدة بشكل منفصل. في مجموعة الكوارتز ، لا تتواصل عقد الكوارتز المستقلة مع عقدة أو عقدة إدارة أخرى ، ولكنها بدلاً من ذلك تتصور تطبيق Quartz آخر من خلال جدول قاعدة البيانات نفسه ، كما هو موضح في الشكل 2.1.
الشكل 2.1 بنية الكتلة الكوارتز
2.2 جداول قاعدة بيانات الكوارتز المرتبطة
نظرًا لأن مجموعة الكوارتز تعتمد على قاعدة البيانات ، فمن الضروري أولاً إنشاء جدول قاعدة بيانات الكوارتز. تتضمن حزمة إصدار الكوارتز البرامج النصية SQL لجميع منصات قاعدة البيانات المدعومة. يتم تخزين البرامج النصية SQL هذه في دليل <Quartz_home>/docs/dbtables. يحتوي الإصدار Quartz 1.8.4 المستخدم هنا على ما مجموعه 12 جدول. قد يكون عدد الجداول مختلفة في الإصدارات المختلفة. قاعدة البيانات هي mySQL ، واستخدم tables_mysql.sql لإنشاء جدول قاعدة بيانات. يتم عرض جميع الجداول في الشكل 2.2 ، ويظهر في الشكل 2.3 مقدمة موجزة لهذه الجداول.
الشكل 2.2 الجداول التي تم إنشاؤها في الكوارتز 1.8.4 في قاعدة بيانات MySQL
الشكل 2.3 مقدمة لجدول بيانات الكوارتز
2.2.1 جدول حالة الجدولة (qrtz_scheduler_state)
الوصف: معلومات مثيل العقدة في الكتلة ، تقرأ الكوارتز معلومات هذا الجدول بانتظام لتحديد الحالة الحالية لكل مثيل في الكتلة.
extal_name: الاسم الذي تم تكوينه بواسطة org.quartz.scheduler.instanceid في ملف التكوين. إذا تم ضبطه على Auto ، فسيقوم Quartz بإنشاء اسم يعتمد على اسم الجهاز الفعلي والوقت الحالي.
last_checkin_time: آخر وقت تسجيل الوصول
checkin_interval: وقت تسجيل الوصول
2.2.2 جدول الجمعية المشغل والتعليم (qRTZ_FIER_TRIGGERS)
تخزن معلومات الحالة المتعلقة بالمعلومات المشغولة وتنفيذ الوظيفة المرتبطة بها.
2.2.3 جدول معلومات الزناد (QRTZ_TRIGGERS)
trigger_name: اسم الزناد ، يمكن للمستخدم تخصيص الاسم في الإرادة ، لا توجد متطلبات قسرة
Trigger_group: اسم مجموعة المشغلات ، والتي يمكن للمستخدم تخصيصها حسب الرغبة ، وليس هناك متطلبات قسرية.
Job_name: المفتاح الأجنبي لـ QRTZ_JOB_DETAILS جدول JOB_NAME
Job_group: qrtz_job_details table job_group المفتاح الأجنبي
Trigger_State: تم تعيين حالة الزناد الحالية على المكتسبة. إذا تم ضبطه على الانتظار ، فلن تؤدي المهمة إلى تشغيل.
Trigger_cron: نوع الزناد ، باستخدام تعبير كرون
2.2.4 جدول تفاصيل المهمة (QRTZ_JOB_DETAILS)
ملاحظة: احفظ تفاصيل المهمة ، يجب تهيئة الجدول بواسطة المستخدم وفقًا للموقف الفعلي
Job_name: اسم الوظيفة في الكتلة. يمكن للمستخدم تخصيص الاسم حسب الرغبة ، دون أي متطلبات قسرية.
Job_group: اسم المجموعة التي تنتمي إليها الوظيفة في المجموعة ، والتي يتم تخصيصها من قبل المستخدم في الإرادة ، وليس هناك متطلبات قسرية.
JOB_CLASS_NAME: اسم الحزمة الكامل لفئة تنفيذ الوظائف في الكتلة. يجد كوارتز فئة الوظيفة بناءً على هذا المسار إلى ClassPath.
is_diable: سواء كان ذلك ، قم بتعيين هذه الخاصية على 1 ، سيستمر Quartz في المهمة في قاعدة البيانات
Job_data: حقل Blob الذي يخزن الأشياء المستمرة.
2.2.5 جدول معلومات الإذن (QRTZ_LOCKS)
ملاحظة: هناك تهيئة DML المقابلة في tables_oracle.sql ، كما هو موضح في الشكل 2.4.
الشكل 2.4 معلومات التهيئة في جدول معلومات إذن الكوارتز
2.3 عملية بدء تشغيل جدولة الكوارتز في الكتلة
لا يلاحظ Quartz Scheduler نفسه أنه متجمع ، وأن JDBC Jobstore فقط الذي تم تكوينه لجدولة ستعرف. عندما يبدأ جدولة Quartz ، فإنه يدعو طريقة SchedulerStarted () لـ Jobstore ، والتي تخبر جدولة Jobstore بأنها بدأت. يتم تنفيذ طريقة SchedulerStarted () في فئة jobstoresupport. تحدد فئة jobstoresupport ما إذا كان مثيل الجدولة يشارك في المجموعة استنادًا إلى الإعدادات في ملف Quartz.properties. إذا تم تكوين المجموعة ، فسيتم إنشاء مثيل لفئة ClusterManager جديدة وتهيئتها وبدء تشغيلها. ClusterManager هو فصل مضمّن في فئة jobstoresupport ، يرث java.lang.thread ، ويعمل بانتظام ويؤدي وظائف تسجيل الوصول على مثيل الجدولة. يحتاج المجدول أيضًا إلى التحقق مما إذا كانت أي عقد كتلة أخرى قد فشلت. يتم تكوين دورة تنفيذ عملية تسجيل الوصول في Quartz.properties.
2.4 اكتشاف عقدة جدولة فاشلة
عندما يقوم مثيل جدولة بإجراء تسجيل الوصول ، فإنه يتحقق مما إذا لم يتم التحقق من حالات جدولة أخرى في الوقت الذي يتوقعون فيه. يتم تحديد ذلك عن طريق التحقق مما إذا كانت قيمة الجدولة المسجلة في عمود Last_Chedk_Time في جدول Scheduler_State قبل Org.quartz.jobstore.clusterCheckinInterval. إذا لم يتم فحص عقد واحد أو أكثر في وقت محدد مسبقًا ، فإن جدولة التشغيل يفترض أنها فشلت.
2.5 استعادة الوظائف من الحالات الفاشلة
عندما تفشل مثيل Sheduler عند تنفيذ وظيفة ، فمن الممكن أن يأخذ مثيل جدولة عمل آخر المهمة ويديرها مرة أخرى. لتحقيق هذا السلوك ، يجب ضبط خاصية استرداد الوظائف التي تم تكوينها على كائن Jobdetail على True (Job.SetRequestSrecovery (True)). إذا تم تعيين الخاصية القابلة للاسترداد على FALSE (الافتراضي كاذب) ، فلن يتم إعادة تشغيله عندما يفشل جدولة في تشغيل المهمة ؛ سيتم تشغيله بواسطة مثيل جدولة آخر في وقت الزناد التالي. مدى سرعة اكتشاف مثيل الجدولة بعد الفشل يعتمد على فاصل تسجيل الوصول لكل جدولة (أي org.quartz.jobstore.clustercheckininterval المذكورة في 2.3).
3. مثيل الكتلة الكوارتز (كوارتز+ربيع)
3.1 Spring غير متوافق مع قضايا الكوارتز
لم يعد الربيع يدعم الكوارتز منذ 2.0.2. على وجه التحديد ، عندما يقوم Quartz+Spring بتثبيت مهمة كوارتز في قاعدة البيانات ، سيحدث خطأ قابل للتسلسل:
<bean id = "jobtask"> <property name = "targetObject"> <ref bean = "quartzjob"/> </property> <property name = "targetmethod"> value> تنفيذ </value> </property> </bean>
لا تدعم طريقة MethodInvoking في فئة MethodInvokingJobDetailfactorybean التسلسل ، لذلك سوف يرمي خطأ عند تسلسل مهمة الكوارتز في قاعدة البيانات.
أولاً ، حل مشكلة methodInvokingJobDetailfactorybean. دون تعديل رمز مصدر الربيع ، يمكنك تجنب استخدام هذه الفئة والاتصال مباشرة بـ JobDetail. ومع ذلك ، فإن استخدام تطبيق JobDetail يتطلب منك تنفيذ منطق Mothodinvking بنفسك. يمكنك استخدام خصائص Jobclass و JobDataasmap لـ JobDetail لتخصيص مصنع (مدير) لتحقيق نفس الغرض. على سبيل المثال ، في هذا المثال ، يتم إنشاء myDetailquartzjobbean جديد لتنفيذ هذه الوظيفة.
3.2 ملف mydetailquartzjobbean.java
Package org.lxh.mvc.jobbean ؛ import java.lang.reflect.method ؛ import org.apache.commons.logging.log ؛ import org.apache.commons.logging.logfactory ؛ import org.quartz.jobexecutiontoxt ؛ org.springframework.context.applicationContext ؛ استيراد org.springframework.scheduling.quartz.quartzjobbean ؛ الطبقة العامة mydetailquartzjobbean تمتد Quartzjobbean {protected logger = logfactory.getlog (getClass () ؛ سلسلة خاصة TargetObject ؛ سلسلة خاصة TargetMethod ؛ Application CTX ApplicationContext ؛ تنفذ الفراغ المحمي (سياق JobexecutionContext) يلقي JobexecutionException {try {logger.info ("تنفيذ [" + targetObject + "] في وقت واحد >>>>>) ؛ Object OargetObject = ctx.getBean (TargetObject) ؛ الطريقة م = فارغة ؛ حاول {m = oargetObject.getClass (). getMethod (TargetMethod ، فئة جديدة [] {}) ؛ M.Invoke (OargetObject ، كائن جديد [] {}) ؛ } catch (SecurityException e) {logger.error (e) ؛ } catch (nosuchmethodException e) {logger.error (e) ؛ }} catch (استثناء e) {رمي JobexecutionException جديد (e) ؛ }} public void setapplicationContext (ApplicationContext ApplicationContext) {this.ctx = applicationContext ؛ } public void settargetObject (String TargetObject) {this.targetObject = targetObject ؛ } public void settargetMethod (String TargetMethod) {this.targetMethod = targetMethod ؛ }}3.3 فئة تنفيذ الوظائف الحقيقية
في فئة الاختبار ، يتم تنفيذ وظيفة طباعة الوقت الحالي للنظام.
package org.lxh.mvc.job ؛ import java.io.serializable ؛ استيراد java.util.date ؛ استيراد org.apache.commons.logging.log ؛ الوصف org.apache.commons.logging.logfactory ؛ public class test serializable استاتيكي خاص نهائي الطويل المسلسل = -2073310586499744415L ؛ public void execute () {date date = new date () ؛ system.out.println (date.tolocalestring ()) ؛ }}3.4 تكوين ملف Quartz.xml
<bean id = "test" scope = "prototype"> </bean> <bean id = "testjobtask"> <property name = "Jobclass"> <value> org.lxh.mvc.jobbean.myDetailquartzjartzjobean </value> </propert key = "targetmethod" value = "execute"/> </map> </property> </boan> <bean name = "testtrigger"> <property name = "jobdetail" ref = "testjobtask"/> <property name = "cronexpression" value = "0/1 * * * * *؟" /> </bean> <bean id = "quartzscheduler"> <property name = "configlocation" value = "classpath: quartz.properties"/> <property name = "triggers"> <list> <ref bean = "testtrigger"/> </list> </propert
3.5 اختبار
رمز وتكوين Servera و ServerB متماثلان تمامًا. ابدأ Servera أولاً ثم ابدأ ServerB. بعد إيقاف تشغيل الخادم ، سيقوم ServerB بمراقبة إيقاف تشغيله وتولي المهمة التي يتم تنفيذها على Servera وتستمر في التنفيذ.
4. مثيل الكتلة الكوارتز (كوارتز واحد)
على الرغم من أننا قمنا بتنفيذ تكوين الكتلة لـ Spring+Quartz ، إلا أنه لا يزال غير مستحسن استخدام هذه الطريقة بسبب مشكلات التوافق بين الربيع والكوارتز. في هذا القسم ، قمنا بتنفيذ مجموعة تم تكوينها بشكل منفصل مع الكوارتز ، وهو بسيط ومستقر مقارنةً بـ Spring+Quartz.
4.1 الهيكل الهندسي
نستخدم الكوارتز وحدها لتنفيذ وظائف الكتلة ، وهيكل الرمز ، وحزم جرة الجهات الخارجية كما هو موضح في الشكل 3.1. من بينها ، إصدار MySQL: 5.1.52 ، وإصدار MySQL لبرنامج التشغيل: MySQL-Connector-Java-5.1.5-bin.jar (مقابل 5.1.52 ، يوصى باستخدام هذا الإصدار من برنامج التشغيل لأنه يوجد خطأ في Quartz أنه لا يمكن تشغيله بشكل طبيعي عند الجمع بين بعض سائقي MySQL).
الشكل 4.1 هيكل هندسة الكتلة الكوارتز وحزم جرة الطرف الثالث المطلوب
من بينها ، Quartz.Properties هو ملف تكوين الكوارتز ووضعه في دليل SRC. إذا لم يكن هناك ملف من هذا القبيل ، فسيقوم الكوارتز تلقائيًا بتحميل ملف Quartz.properties في حزمة JAR ؛ SimplerCoveryJob.Java و SimplerCoveryStateFuljob.java هي وظيفتان ؛ ClusterExample.java يكتب معلومات الجدولة ، وآلية التشغيل والوظائف الرئيسية الاختبار المقابلة.
4.2 ملف التكوين quartz.properties
يتم استخدام اسم الملف الافتراضي quartz.properties لتنشيط ميزة الكتلة عن طريق تعيين "org.quartz.jobstore.iscolustered" إلى "True". يجب أن يكون لكل مثيل في المجموعة "معرف مثيل" فريد ("org.quartz.scheduler.instanceid") ، ولكن يجب أن يكون له نفس "اسم مثيل الجدولة" ("org.quartz.scheduler.instancename") ، وهو ما يعني أن كل مثيل في المجموعة يجب أن يستخدم نفس ملف Quartz.Propileties. باستثناء الاستثناءات التالية ، يجب أن تكون محتويات ملف التكوين هي نفسها:
أ. حجم تجمع الموضوع.
ب. مختلفة "org.quartz.scheduler.instanceid" قيم السمة (فقط تعيين على "Auto").
#============================================================= =============================================================== =============================================================== =============================================================== =============================================================== =============================================================== =============================================================== =============================================================== Auto#======================================================================================== ============================================================================================================================ org.quartz.jobstore.impl.jdbcjobstore.jobstoretxorg.quartz.jobstore.driverdlegateClass = org.quartz.impl.jdbcjobstore.stdjdbcdlegateorg.quartz.jobstore.table qrtz_org.quartz.jobstore.isclustered = trueorg.quartz.jobstore.clusterCheckinInterval = 10000 org.quartz.jobstore.datasource = myds #============================================================================================== ============================================================================================== ============================================================================================== ============================================================================================== #=========================================================================================================== com.mysql.jdbc.driverorg.quartz.datasource.myds.url = jdbc: mysql: //192.168.31.18: 3306/test؟ useUnicode = true & distarrencoding = utf-8org.quartz.dataSource 123456org.quartz.datasource.myds.MaxConnections = 30#======================================================= ========================================================== ========================================================== ========================================================== ========================================================== ========================================================== ========================================================== ========================================================== org.quartz.simpl.simplethreadpoolorg.quartz.threadpool.ThreadCount = 5org.quartz.threadpool.ThreadPriority = 5org.quartz.throadpool.threadsinhercontextClasslassloaderOfinitialization = true
4.3 ملف clusterexample.java
مجموعة الحزمة ؛ استيراد java.util.date ؛ استيراد org.quartz.jobdetail ؛ استيراد org.quartz.scheduler ؛ استيراد org.quartz.schedulerfactory ؛ استيراد org.quartz.simpletrigger atcheduler) يلقي الاستثناء {system.out.println ("**** حذف الوظائف/المشغلات الحالية *****") ؛ // unschedule Jobs string [] groups = anccheduler.getTriggerGroupNames () ؛ لـ (int i = 0 ؛ i <groups.length ؛ i ++) {string [] names = anccheduler.getTriggerNames (المجموعات [i]) ؛ لـ (int j = 0 ؛ j <names.length ؛ j ++) {inscheduler.unschedulejob (أسماء [j] ، المجموعات [i]) ؛ }} // حذف مجموعات الوظائف = ischeduler.getjobgroupnames () ؛ لـ (int i = 0 ؛ i <groups.length ؛ i ++) {string [] names = anccheduler.getJobNames (المجموعات [i]) ؛ لـ (int j = 0 ؛ j <names.length ؛ j ++) {inscheduler.deletejob (أسماء [j] ، المجموعات [i]) ؛ }}} Run public void (Boolean Inclearnearjobs ، boolean enschedulejobs) يلقي الاستثناء {// أولاً يجب أن نحصل على إشارة إلى Schedulerfactory Sf = new StdScheDulerFactory () ؛ Scheduler Sched = sf.getScheduler () ؛ if (inteRegLeBs) {cleanup (Screed) ؛ } system.out.println ("-----------------------------") ؛ if (anchedulejobs) { System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- إعادة تنفيذ هذه المهمة إذا كان الجدولة قد انخفض ... سيتم تشغيله على: " + trigger.getNextFiretime () +" وكرر: " + trigger.getRepeatCount () +" مرات ، كل " + trigger.getRepeAtinterval () / 1000 + SimplerCoveryStateful.class). system.out.println (job.getfullname () + "سيتم تشغيله على:" + trigger.getNextFiretime () وكرر: تم استدعاؤه ... system.out.println ("------------------------------------------") ؛ System.out.println("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Thread.sleep(3600L * 1000L) ؛ System.out.println ("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- args.length ؛ }}4.4 SimplerCoveryJob.java
مجموعة الحزمة ؛ استيراد java.io.serializable ؛ استيراد java.util.date ؛ استيراد org.apache.commons.logging.log ؛ import org.apache.commons.logging.logfactory ؛ الوظائف التي تريد تنفيذها مرارًا وتكرارًا ، اكتب الكود ذي الصلة في طريقة التنفيذ ، والفرضية هي: تنفيذ واجهة الوظيفة // كما هو الحال عندما يتم إنشاء فئة SimpleJob ، وعندما يتم استدعاء طريقة التنفيذ ، لا نحتاج logfactory.getLog (SimplerCoveryJob.class) ؛ Public SimplerCoveryJob () {} تنفيذ الفراغ العام (سياق JobexecutionContext) يلقي JobexecutionException {// هذه المهمة ببساطة طباعة اسم الوظيفة والوقت الذي تقوم فيه المهمة بتشغيل string jobname = context.getjobdetail (). getfullname () ؛ System.out.println ("Job 111111111111111 SimplerCoveryJob يقول:" + JobName + "تنفيذ في" + New Date ()) ؛ }}4.5 نتائج التشغيل
التكوين والرمز في الخادم A والخادم B متماثلان تمامًا. طريقة التشغيل: Run ClusterExample.java على أي مضيف ، وأضف المهمة إلى الجدول ، ومراقبة نتائج التشغيل:
Run Servera ، يتم عرض النتائج في الشكل 4.2.
الشكل 4.2 نتيجة تشغيل Servera 1
بعد تشغيل ServerB ، يظهر إخراج Servera و ServerB في الشكلين 4.3 و 4.4.
الشكل 4.3 النتيجة تشغيل Servera 2
الشكل 4.4 نتيجة تشغيل ServerB 1
يمكن ملاحظة من الشكلين 4.3 و 4.4 أنه بعد تشغيل ServerB ، يدرك النظام تلقائيًا مسؤولية التوازن ، ويتولى ServerB مهام Job1. بعد إيقاف تشغيل Servera ، يتم عرض نتائج تشغيل ServerB في الشكل 4.5.
الشكل 4.5 نتيجة تشغيل ServerB 2
كما يتضح من الشكل 4.5 ، يمكن لـ ServerB اكتشاف أن Servera يتم فقده ، وتولي المهمة المهمة 2 ، وتفقد Servera إلى Job2 الذي يجب تنفيذه خلال وقت الاستثناء هذا.
5. أشياء يجب ملاحظتها
5.1 مشكلة التزامن الوقت
لا يهتم الكوارتز فعليًا ما إذا كنت تقوم بتشغيل العقد على نفس الآلات أو مختلف الآلات. عندما يتم وضع كتلة على أجهزة مختلفة ، يطلق عليها مجموعة أفقية. عندما تعمل العقدة على نفس الجهاز ، يطلق عليها مجموعة رأسية. بالنسبة للمجموعات الرأسية ، هناك مشكلة في نقطة فشل واحدة. هذا غير مقبول لتطبيقات توفر عالية ، لأنه بمجرد تعطل الجهاز ، يتم إنهاء جميع العقد. بالنسبة للمجموعات الأفقية ، هناك مشكلة في التزامن الوقت.
تستخدم العقدة طابعًا زمنيًا لإخطار الحالات الأخرى في وقت تسجيل الوصول الأخير. إذا تم ضبط ساعة العقدة على الوقت المستقبلي ، فلن يدرك جدولة التشغيل أن العقدة قد انخفضت. من ناحية أخرى ، إذا تم ضبط ساعة العقدة على الوقت الماضي ، فربما تحدد العقدة الأخرى أن العقدة قد سقطت ومحاولة أخذ وظيفتها وإعادة تشغيلها. أسهل طريقة لمزامنة ساعة الكمبيوتر هي استخدام خادم وقت الإنترنت.
5.2 مشكلة العقد التي تتنافس على الوظائف
نظرًا لأن الكوارتز يستخدم خوارزمية موازنة التحميل العشوائية ، يتم تنفيذ المهمة بواسطة مثيلات مختلفة بطريقة عشوائية. ذكر موقع Quartz الرسمي أنه في الوقت الحاضر ، لا توجد طريقة لتعيين (PIN) وظيفة إلى عقدة معينة في الكتلة.
5.3 إصدار للحصول على قائمة عمل من الكتلة
حاليًا ، إذا لم تدخل استعلام قاعدة البيانات مباشرة ، فلا توجد طريقة بسيطة للحصول على قائمة بجميع الوظائف التنفيذية في المجموعة. لن يحصل طلب مثيل جدولة فقط على قائمة بالوظائف التي تعمل على هذا المثال. يوصي موقع Quartz الرسمي بأن يمكنك الحصول على جميع معلومات الوظيفة من الجدول المقابل عن طريق كتابة بعض رمز JDBC للوصول إلى قاعدة البيانات.
لخص
ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون لمحتوى هذه المقالة قيمة مرجعية معينة لدراسة أو عمل الجميع. إذا كان لديك أي أسئلة ، فيمكنك ترك رسالة للتواصل. شكرا لك على دعمك إلى wulin.com.