2011-11-23 20 views
5

चल रहा है मैं महीने के पहले दिन मध्यरात्रि में एक विशिष्ट कार्य चलाने के लिए स्प्रिंग के साथ क्वार्ट्ज का उपयोग कर रहा हूं। मैंने सर्वर की शुरुआत & महीने के आखिरी दिन 11:59 होने के समय, सर्वर से शुरू करने और 12:00 बजे तक चलने वाले कार्य को देखकर नौकरी का परीक्षण किया है, लेकिन मैं उन मामलों के बारे में चिंतित हूं जहां मामलों के बारे में चिंतित है सर्वर (किसी भी कारण से) महीने के पहले को मध्यरात्रि में नहीं चल रहा है।एक मिस्ड क्वार्ट्ज जॉब

मुझे लगता है कि क्वार्ट्ज में मिस्फीयर हैंडलिंग इस पर ध्यान रखेगी, लेकिन शायद मैं उस पर गलत हूं?

क्या कोई मुझे सलाह दे सकता है कि मैं इसे कैसे संभालने में सक्षम हूं? मैं वास्तव में ऐसी नौकरी नहीं बनाना चाहूंगा जो हर 'एक्स' सेकंड/मिनट/घंटे चलाता है और यह देखने के लिए जांच करें कि क्या मुझे नौकरी चलाने की ज़रूरत है अगर मैं इससे बच सकूं।

मैं भी उत्सुक हूं कि मुझे कोई क्वार्ट्ज संबंधित लॉगिंग जानकारी क्यों नहीं दिखाई दे रही है, लेकिन यह एक माध्यमिक मुद्दा है।

यहाँ कार्य के लिए मेरी वसंत विन्यास है:

<bean id="schedulerService" class="com.bah.pams.service.scheduler.SchedulerService"> 
    <property name="surveyResponseDao" ref="surveyResponseDao"/> 
    <property name="organizationDao" ref="organizationDao"/> 
</bean> 

<bean name="createSurveyResponsesJob" class="org.springframework.scheduling.quartz.JobDetailBean"> 
    <property name="jobClass" value="com.bah.pams.service.scheduler.jobs.CreateSurveyResponsesJob"/> 
    <property name="jobDataAsMap"> 
     <map> 
      <entry key="schedulerService" value-ref="schedulerService"/> 
     </map> 
    </property> 
</bean> 
<!-- Cron Trigger --> 
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> 
    <property name="jobDetail" ref="createSurveyResponsesJob"/> 
    <property name="cronExpression" value="0 0 0 1 * ? *"/> 
    <!--if the server is down at midnight on 1st of month, run this job as soon as it starts up next --> 
    <property name="misfireInstructionName" value="MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"/> 
</bean> 

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 

    <property name="autoStartup" value="true"/> 

    <property name="quartzProperties"> 
     <props> 
      <prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop> 
      <prop key="org.quartz.jobStore.misfireThreshold">60000</prop> 
     </props> 
    </property> 
    <property name="jobDetails"> 
     <list> 
      <ref bean="createSurveyResponsesJob"/> 
     </list> 
    </property> 

    <property name="triggers"> 
     <list> 
      <ref bean="cronTrigger"/> 
     </list> 
    </property> 
</bean> 

उत्तर

2

MISFIRE_INSTRUCTION_FIRE_ONCE_NOW उद्देश्य आप का उल्लेख के लिए है और यदि आप सर्वर (रों) के एक बंद संदेह है कि आप निश्चित रूप से JVM स्मृति से बाहर अपनी नौकरी जारी रहती है चाहिए (उदा: RAMJobStore के बजाय एक जेडीबीसी जॉबस्टोर का उपयोग करके)।

रैमजोबस्टोर तेज़ और हल्का है, लेकिन प्रक्रिया समाप्त होने पर सभी शेड्यूलिंग जानकारी खो जाती है।

http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigRAMJobStore

JDBCJobStore का समय निर्धारण जानकारी (काम, ट्रिगर और कैलेंडर) एक संबंधपरक डेटाबेस के भीतर स्टोर करने के लिए प्रयोग किया जाता है।

http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigJobStoreTX

आशा है कि यह मदद करते हैं।

0

मुझे भी सर्वर पुनरारंभ पर अंतिम अनुसूचित नौकरी चलाने की इच्छा का सामना करना पड़ा है।

यह समाधान है जो मैंने पाया है कि ट्रिगर के लिए एक बार अंतराल वापस जाना है और अगले फायरिंग समय की गणना करना है। सभी ट्रिगरों के माध्यम से पुनरावृत्ति करके सबसे हालिया समय जब अतीत में एक ट्रिगर को निकाल दिया जाना चाहिए, तो निर्धारित किया जा सकता है।


प्रत्येक फायरिंग के बीच अंतराल की गणना करें:

Date nextFireTime = trigger.getNextFireTime(); 
Date subsequentFireTime = trigger.getFireTimeAfter(nextFireTime); 
long interval = subsequentFireTime.getTime() - nextFireTime.getTime(); 

अतीत में अंतराल जब तक कि एक समय के लिए अगले फायरिंग समय खोजें:

Date previousPeriodTime = new Date(System.currentTimeMillis() - interval); 
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime); 

मैं ने पाया है कि यदि आप उपयोग कर रहे हैं एक CronTrigger यह आपको अतीत में आग का समय बचाने के लिए रोकता है।ट्रिगर के सभी के माध्यम से

Date originalStartTime = trigger.getStartTime(); // save the start time 
Date previousPeriodTime = new Date(originalStartTime.getTime() - interval); 
trigger.setStartTime(previousPeriodTime); 
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime); 
trigger.setStartTime(originalStartTime); // reset the start time to be nice 

दोहराएं और एक है कि सबसे हाल ही में अतीत में मिल: इस हल करने के लिए मैं शुरू करने का समय संशोधित है, इसलिए ऊपर टुकड़ा हो जाता है

for (String groupName : scheduler.getTriggerGroupNames()) { 
    for (String triggerName : scheduler.getTriggerNames(groupName)) { 
     Trigger trigger = scheduler.getTrigger(triggerName, groupName); 
     // code as detailed above... 
     interval = ... 
     previousFireTime = ... 
    } 
} 

मैं इसे हेलर विधियों या कक्षाओं में पुन: सक्रिय करने के लिए पाठक को एक अभ्यास के रूप में छोड़ देंगे। मैं वास्तव में उप-वर्गीकृत प्रतिनिधि ट्रिगर में उपर्युक्त एल्गोरिदम का उपयोग करता हूं जिसे मैं पिछले फायरिंग समय द्वारा क्रमबद्ध सेट में रखता हूं।

संबंधित मुद्दे