2010-07-23 16 views
9

मेरे पास नौकरी निर्धारित करने के लिए क्वार्ट्ज शेड्यूलर का उपयोग कर एक आवेदन है। एप्लिकेशन वर्तमान में क्वार्ट्ज संस्करण 1.6.2 चला रहा है। मेरा जॉबस्टोर org.quartz.impl.jdbcjobstore.JobStoreTX है जो ओरेकल डेटाबेस का समर्थन करता है। क्लस्टरिंग चालू है, लेकिन डेटाबेस का उपयोग कर केवल एक शेड्यूलर है।क्या मैं ट्रिगर किए गए क्रम में क्वार्ट्ज नौकरियों की आग का इंतजार कर सकता हूं?

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool 
org.quartz.threadPool.threadCount = 5 
org.quartz.threadPool.threadPriority = 5 

मेरे नौकरियों लंबी चलने वाली हैं, तो यह ट्रिगर नए रोजगार आग चल 5 नौकरियों (अधिकतम मेरी thead पूल द्वारा अनुमति) के लिए काफी आम है: मेरे क्वार्ट्ज ThreadPool इस प्रकार किया गया है। नव शुरू हो नौकरियों मिसफायर और मैं निम्नलिखित जैसे संदेश लॉग ऑन देखें:

2011-05-20 04:09:30,097 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:08:29 05/20/2011 
2011-05-20 04:09:30,120 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:09:30 05/20/2011 
2011-05-20 04:09:30,125 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:08:30 05/20/2011 
2011-05-20 04:09:30,138 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:09:30 05/20/2011 
2011-05-20 04:11:29,998 INFO [QuartzScheduler_scheduler-servername-111305822376676_MisfireHandler] o.q.impl.jdbcjobstore.JobStoreTX - Handling 2 trigger(s) that missed their scheduled fire-time. 

एक बार एक चल रहा है काम खत्म, misfired नौकरियों में से एक को उठाया जाएगा और सामान्य रूप से चलाते हैं। हालांकि, क्वार्ट्ज यादृच्छिक रूप से एक मिस्फ़र्ड नौकरी लेने लगता है, इस बात के संबंध में कि नौकरियों को मूल रूप से निष्पादित करने के लिए निर्धारित किया गया था। आदर्श रूप से, मैं उन्हें अपने मूल अग्नि काल के आधार पर चलाने के क्रम में उठाया जाना चाहता हूं।

क्या क्वार्ट्ज थ्रेडपूल में एक बार स्थानांतरित होने के बाद मेरी प्रतीक्षा (मिस्फार्ड) नौकरियों को निकाला जा सकता है ताकि वे ट्रिगर हो जाएं?

उत्तर

2

जब क्वार्ट्ज एक ट्रिगर को संभालता है जिसने इसे आग का समय गंवा दिया है तो यह ट्रिगर के nextFireTime को अपडेट करेगा। डिफ़ॉल्ट रूप से एक ट्रिगर को मिस माना जाएगा यदि यह अगला है FireTime अतीत में 60 सेकंड से अधिक है। मिस्ड ट्रिगर्स को अभी भी अगलीफायरटाइम और प्राथमिकता ऑर्डर के आधार पर चुना जाना चाहिए, लेकिन मुझे लगता है कि यह यादृच्छिक प्रतीत होता है क्योंकि कुछ ट्रिगर अपडेट किए गए हैं और अन्य नहीं हैं।

मैं org.quartz.jobStore.misfireThreshold संपत्ति को बढ़ाने का सुझाव दूंगा। http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigRAMJobStore.html देखें (हालांकि संपत्ति सभी जॉबस्टोर के लिए समान है)। इससे आपके ट्रिगर्स को फिर से निर्धारित करने की संभावना कम होनी चाहिए।

+0

मैं वास्तव में इसका परीक्षण नहीं कर सकता क्योंकि मुझे एक नया काम मिला है, वर्षों में क्वार्ट्ज का उपयोग नहीं किया है, और यह देखने के लिए कि यह काम करता है या नहीं, परीक्षण परियोजना स्थापित करने के लिए परेशान नहीं किया जा सकता है। हालांकि, मुझे प्रभावित है कि आपने 5 साल के पुराने प्रश्न का उत्तर देने के लिए परेशान किया है, और आपका उत्तर उपयोगी लगता है, इसलिए मैं आगे बढ़ने वाला हूं और इसे हल करने के रूप में चिह्नित करता हूं :) –

+0

मुझे एक समान समस्या थी इसलिए खोज रहा था स्टैक ओवरफ़्लो। अंत में मैंने कोड के माध्यम से खोद लिया और खुद को समझ लिया लेकिन सोचा कि अगर मैं भविष्य में किसी और के जवाब की तलाश कर रहा हूं तो मैं इसे यहां छोड़ दूंगा। – samblake

+0

@ जोनक्वार्फोथ अंत में आपके लिए क्या काम करता है? मैं हजारों नौकरी का समय निर्धारित कर रहा हूं और नौकरी लंबे समय तक चल रही है क्योंकि मुझे स्थान से दूसरे स्थान पर ब्लॉब माइग्रेट करने की आवश्यकता है और वे ब्लब्स 100 जीबी जितना बड़ा हो सकते हैं। मैं क्वार्ट्ज क्लस्टरिंग का उपयोग करने की योजना बना रहा हूं ताकि जब मास्टर नौकरी को शेड्यूल कर लेता है, दास उन नौकरियों पर काम करते रहेंगे और मुझे वास्तव में मिस आग की परवाह नहीं है क्योंकि मुझे अंत में दासों में से एक द्वारा उठाए गए नौकरी की परवाह है । शायद मैं एक हास्यास्पद बड़े मिस्फीयर दहलीज मूल्य निर्धारित कर सकते हैं। कृपया मुझे बताएं कि आप इसके बारे में क्या सोचते हैं। धन्यवाद। – Coder

0

क्वार्ट्ज thread pool पर देखकर, यह प्रतीक्षा()/अधिसूचित() लूप का उपयोग करता है, जो उचित नहीं है, और कई थ्रेड प्रतीक्षा होने पर यादृच्छिक रूप से एक नया धागा चुन देगा।

आप थ्रेडपूल के अपने उदाहरण का उपयोग कर सकते हैं जो उचित है। कोड को SimpleThreadPool से कॉपी करें, लेकिन अगले runnableLock के चारों ओर लॉकिंग को java.util.ReentrantLock के साथ बदलें, जो निष्पक्ष कन्स्ट्रक्टर को सच हो। आपके संशोधित SimpleThreadPool में, सिंक्रनाइज़ किए जाने के बजाय ReentrantLock.lock()/unlock() का उपयोग करें, और प्रतीक्षा/सूचित करने के बजाय ReentrantLock.newCondition() सिग्नल()/await() का उपयोग करें, और यह आपकी समस्या का समाधान कर सकता है।

+0

पूल में उन धागे में उन्हें नौकरी नहीं दी गई है, इसलिए आप जिस निष्पक्षता के बारे में बात कर रहे हैं, इससे कोई फर्क नहीं पड़ता। जो भी धागे पहले आते हैं, वह अगली नौकरी चलाएगा। – jhouse

+0

मुझे लगता है कि निष्पक्षता थ्रेड पूल के बाहर धागे से आती है, runInThread और blockForAvailableThreads दोनों प्रतीक्षा करें। जब आपने कहा था, "मेरा धागा पूल अधिकतम हो गया है, तो" – sbridges

+0

runInThread() और blockForAvailableThreads() दोनों को एक ही धागे से बुलाया जाता है - उन तरीकों के परिणाम के लिए कई धागे इंतजार नहीं कर रहे हैं, इसलिए 'निष्पक्षता' प्रतीक्षा करें()/सूचित करें() कोई फर्क नहीं पड़ता। (केवल एक थ्रेड सेवाएं/थ्रेड पूल का उपयोग करती है)। – jhouse

2

मुझे लगता है कि आप एक मिस्फायरिंग परिदृश्य में चल रहे हैं (एक परिदृश्य जहां कार्यकर्ता धागे की तुलना में निष्पादित करने के लिए और अधिक नौकरियां तैयार हैं)। ट्रिगर्स पर मिस्फायर निर्देश और/या प्राथमिकता संपत्ति सेट करें ताकि यह बदला जा सके कि प्रत्येक व्यक्ति अपने आग के समय से पहले कैसे व्यवहार करता है।

इसके अलावा, आप मिस्फीयर थ्रेसहोल्ड को बढ़ाने पर विचार कर सकते हैं, जो एक ट्रिगर "देर से" थ्रेड के लिए इंतजार कर सकता है जब इसे मिस्फायर माना जाता है (और इसके मिस्फीयर निर्देश को इसके लिए लागू किया जाता है))।

क्या क्वार्ट्ज थ्रेडपूल में एक बार स्थान मिलने के बाद मेरी प्रतीक्षा (मिस्फार्ड) नौकरियों को निकालने के क्रम में निकाल दिया जा सकता है?

"कुछ भी नहीं" निर्देश आग के समय के रूप में छोड़ देंगे।

+0

यह निश्चित रूप से एक मिस्फीयर परिदृश्य है - मैंने उस बिंदु पर थोड़ा और विशिष्ट होने के लिए प्रश्न अपडेट किया है। क्या कोई मिस्फीयर निर्देश है जो मिस्फायर जॉब्स को इस क्रम में उठाया जाएगा कि उन्हें मूल रूप से निकाल दिया गया था? –

+3

MISFIRE_INSTRUCTION_DO_NOTHING मिस्फीयर के लिए जावाडोक निम्नानुसार पढ़ता है: "शेड्यूलर को निर्देश देता है कि एक गलत आग की स्थिति पर, क्रोन ट्रिगर वर्तमान समय के बाद शेड्यूल में अगली बार अपडेट किया गया है, लेकिन यह करता है अब नहीं निकालना चाहते हैं। " शायद मैं गलत समझता हूं, लेकिन यह मुझे लगता है कि नौकरी की तरह ही फायरिंग छोड़ दी जाएगी और अगली बार ट्रिगर होने तक कुछ भी नहीं करेगा। यह वह नहीं है जिसकी मुझे चाहत है। मैं चाहता हूं कि जैसे ही धागे उपलब्ध हों, नौकरी चलाना चाहें, लेकिन सबसे लंबे समय तक प्रतीक्षा करने वाली नौकरियों के साथ पहली बार कई मिस्फायर नौकरियां हैं। –

0

एक CronTrigger के मामले में, विधि updateAfterMisfire() कार्य new Date() मामले MISFIRE_INSTRUCTION_FIRE_ONCE_NOW नीति पर फिर से तय कर सकते हैं।

यदि कई कार्य मिस्फ़र्ड हैं, तो उनमें से कई एक ही समय (उसी मिलीसेकंद) पर पुनर्निर्धारित किए जा सकते हैं, क्योंकि कंप्यूटर तेजी से चलता है।

परिणामस्वरूप, और यदि कोई प्राथमिकता परिभाषित नहीं की गई है, तो शेड्यूलर पहले अगले कार्य को उठाएगा, सभी NextFireTime के साथ, कुंजी या पूर्ण नाम के अनुसार।

updateAfterMisfire() विधि को उदाहरण के रूप में Thread.sleep(25) का उपयोग करके एक अद्वितीय date पर कार्य को फिर से शेड्यूल करना चाहिए था।

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

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