2016-01-13 5 views
5

मेरे पास दो कार्य हैं जिन्हें मुझे task1 और task2 कहने की आवश्यकता है जो एक ही व्यवसाय प्रक्रिया का हिस्सा हैं। मुझे task1 पूर्ण होने पर अंतिम उपयोगकर्ता को प्रतिक्रिया देना होगा ताकि प्रतिक्रिया समय को कम किया जाना चाहिए।ईजेबी असिंक्रोनस विधियों का उपयोग करने का सही तरीका

मेरा वर्तमान दृष्टिकोण task1 निष्पादित करना है और जैसे ही task1 समाप्त हो गया है, task2 विधि को अतुल्यकालिक रूप से लागू करें। task2 जटिल है और इसका प्रतिक्रिया समय मेरे नियंत्रण से बाहर है क्योंकि इसमें कुछ बाहरी निर्भरता है।

@Stateless 
public class SessionBean1 { 

    @Inject 
    SessionBean2 sessionBean2; 

    public void doTask1(){ 
     // task one stuff 
     sessionBean2.doTask2(); 
    } 

} 



@Stateless 
public class SessionBean2 { 

    @Asynchronous 
    public void doTask2(){ 
     // do task2 stuff 
    } 

} 

websphere 8.0 (प्रयोग में EJB कंटेनर) तुल्यकालिक तरीके और अतुल्यकालिक तरीकों में अलग धागा पूल द्वारा चलाए जा रहे हैं।

मेरी प्रारंभिक धारणा यह थी कि task2 बुरी तरह से प्रदर्शन कर रहा है, task1 का कोई प्रभाव नहीं होगा, लेकिन दुख की बात यह सच नहीं है।

यदि task2 बुरी तरह से प्रदर्शन कर रहा है, तो एसिंक्रोनस थ्रेड पूल से सभी धागे पर कब्जा कर लिया जाएगा। यह task1 का कारण बन जाएगा ताकि एसिंक्रोनस थ्रेड मुक्त हो जाएं और इसलिए task1 पर प्रभाव पड़ता है।

websphrere सर्वर लॉग में संदेश: The request buffer for thread pool WorkManager.WebSphere_EJB_Container_AsynchMethods_Internal_WorkManager has reached its capacity

मेरा प्रश्न है कि मैं क्या यहाँ क्या हासिल करने की कोशिश कर रहा हूँ प्राप्त करने के लिए एक उचित तरीका होगा है।

+0

यदि आप जावा ईई 7 का उपयोग कर रहे थे, तो आप @AccessTimeout (value = xx) एनोटेशन का उपयोग कर सकते हैं, लेकिन मुझे लगता है कि वेबस्पेयर जावा ईई 6 है? – rjdkolb

+0

@mattfreake: जैसा कि लिंक [छवि] में है (http://2.1m.yt/itzn6So।jpg), async विधि अनुरोधों की संख्या सीमित हैं और async धागे की संख्या पर निर्भर हैं। मैं धागे की संख्या बढ़ा सकता हूं लेकिन यहां तक ​​कि अगर कुछ मिनटों के लिए task2 बुरी तरह से प्रदर्शन करता है, तो मेरे कार्य 1 को अभी भी इंतजार करना होगा। हार्डवेयर कॉन्फ़िगरेशन द्वारा थ्रेड की संख्या सीमित नहीं है। – ares

+1

@rjdkolb द्वारा सुझाए गए जेएमएस कतार का उपयोग करने का विचार थ्रेड पूल का आकार बदलना मुश्किल है। –

उत्तर

2

कॉल करने के लिए एक अन्य विकल्प "काम अनुरोध कतार को बढ़ाने के लिए किया जाएगा की आवश्यकता होगी व्यवस्थापक कंसोल में "ईजेबी एसिंक्रोनस विधि आमंत्रण सेटिंग्स" का आकार "। वास्तविक धागा पूल से पहले यह एक कतार है, इसलिए यह आपको कुछ और समय खरीद सकता है।

आदर्श रूप से यह ऊपर सुझाए गए टाइमआउट के साथ संयोजन में उपयोग किया जाना चाहिए।

+0

यह एक अच्छा विकल्प लगता है। डिफ़ॉल्ट रूप से इसे रन टाइम द्वारा नियंत्रित किया जाता है और आवंटित धागे पर निर्भर करता है लेकिन मैं यह नहीं समझ सकता कि कितने। क्या websphrere व्यवस्थापक कंसोल से पिछली पंक्ति 'रनटाइम वर्तमान में 20 के बड़े और थ्रेड की अधिकतम संख्या के मान का उपयोग करती है' कोई समझ में आता है? – ares

+0

अपनी छवि को देखते हुए, मैं इसे "15 या 20 का बड़ा" मानता हूं, इसलिए आपके मामले में यह 20 होना चाहिए। आप 15 अधिकतम थ्रेड-पूल आकार को रख सकते हैं, और अपनी कतार को कुछ अधिक बढ़ा सकते हैं। मुझे उम्मीद है कि कतार में एक छोटी मेमोरी/प्रोसेसर पदचिह्न होना चाहिए, इसलिए यह आपके हार्डवेयर की सीमाओं को समाप्त करने और रखने के दौरान, कार्य 2 के लिए आपके प्रतीक्षा अनुरोधों को संग्रहीत कर सकता है। लेकिन अगर टास्क 2 खत्म होने के लिए अनिश्चित समय ले सकता है, तो मुझे लगता है कि टाइमआउट जाने का रास्ता होगा –

2

मुझे लगता है कि @AccessTimeout वह है जिसे आप ढूंढ रहे हैं। मुझे एक उदाहरण here यह उस समय की सीमा को सीमित करेगा जो .doTask2() चला सकता है और आपकी समस्या से बच सकता है।

@Stateless 
public class SessionBean1 { 

    @Inject 
    SessionBean2 sessionBean2; 

    public void doTask1(){ 
     // task one stuff 
     sessionBean2.doTask2(); 
    } 

} 

SessionBean2

@Stateless 
public class SessionBean2 { 
    @AccessTimeout(60000)//default timeunit is TimeUnit.MILLISECONDS 
    @Asynchronous 
    public void doTask2(){ 
     // do task2 stuff 
    } 

} 

एक विकल्प के रूप:

समय async प्रक्रिया ले जा सकते हैं सीमित करने के लिए, handle.get का उपयोग (xx, TimeUnit.xx); तरीका। आपको भविष्य को वापस करने की आवश्यकता होगी और इसे काम करने के लिए केवल शून्य नहीं होगा।

मुझे आशा है कि इस सूट आपके उपयोग के मामले के रूप में आप एक .Get

@Stateless 
public class SessionBean1 { 

    @Inject 
    SessionBean2 sessionBean2; 

    public void doTask1(){ 
     // task one stuff 
     Future<Void> handle = sessionBean2.doTask2(); 
     // do other stuff 
     handle.get(10, TimeUnit.SECONDS);//If you want to block later 

    } 

} 

SessionBean2

@Stateless 
public class SessionBean2 { 

    @Asynchronous 
    public Future<Void> doTask2(){ 
     // do task2 stuff 
     new AsyncResult<Void>(Void); 
    } 

} 
+0

मैं @AccessTimeout जोड़ने के बाद परीक्षण लोड करूंगा और आपको परिणाम बता दूंगा। लेकिन ऐसे मामलों में जब कॉल वास्तव में टाइमआउट होगा, तो मेरे टास्क 2 को नहीं बुलाया जाएगा। – ares

+1

यदि आप इसे असीमित और हमेशा चलाना चाहते हैं, तो एक संदेश एक जेएमएस कतार – rjdkolb

+0

... या एक ईजेबी टाइमर का उपयोग करें, जो उपयोग करने में आसान है। –

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