2017-01-26 11 views
5

हमारे पास कुछ अनोखा मामला है जहां हमें बाहरी एपीआई के साथ इंटरफ़ेस करने की आवश्यकता है जिसके लिए हमें वास्तविक समय ईवेंट के लिए अपने एंडपॉइंट को लंबे समय तक मतदान करने की आवश्यकता होती है।वसंत में लंबे मतदान

बात यह है कि हमारे पास किसी भी समय इस अंतराल को मारने वाले 80,000 लोग/डिवाइस हो सकते हैं, घटनाओं को सुन सकते हैं, डिवाइस/व्यक्ति प्रति कनेक्शन 1 कनेक्शन।

जब कोई ग्राहक हमारी स्प्रिंग सेवा से घटनाओं के लिए लंबे मतदान तक अनुरोध करता है, तो हमारी सेवा बदले में बाहरी एपीआई को घटनाओं के लिए लंबे मतदान के लिए एसिंक कॉल बनाती है। बाहरी एपीआई ने को न्यूनतम परिभाषित किया है, लंबे मतदान समय सीमा 180 सेकंड पर सेट की जा सकती है।

तो यहां हमारे पास ऐसी स्थिति है जहां एक कतार वाला धागा पूल काम नहीं करेगा, क्योंकि अगर हमारे पास कुछ थ्रेड पूल (5 मिनट, 10 अधिकतम, 10 कतार) है तो 10 धागे पर काम हो रहा है स्पॉटलाइट और 10 कतार में एक मौका नहीं मिलेगा जब तक कि मौजूदा 10 में से कोई एक नहीं किया जाता है।

हमें इसकी सेवा करने या इसे विफल करने की आवश्यकता है (हम इसके पीछे लोड बैलेंसर्स इत्यादि रखेंगे), लेकिन हम वास्तविक मतदान के बिना क्लाइंट फांसी छोड़ना नहीं चाहते हैं।

हम इसके लिए DeferredResult का उपयोग करने और नियंत्रक से लौटने में देख रहे हैं।

@RequestMapping(value = "test/deferredResult", method = RequestMethod.GET) 
    DeferredResult<ResponseEntity> testDeferredResult() { 
     final DeferredResult<ResponseEntity> deferredResult = new DeferredResult<ResponseEntity>(); 
     CompletableFuture.supplyAsync(() -> testService.test()).whenCompleteAsync((result, throwable) -> deferredResult.setResult(result)); 
     return deferredResult; 
    } 

मैं अगर मैं सही रास्ते पर हूँ CompletableFuture.supplyAsync() विधि से पूछताछ कर रहा हूँ, और यह भी मैं एक प्रबंधक और प्रबंधक (और विन्यास) किस तरह का सबसे अच्छा प्रदान करना चाहिए पूरा करने के लिए की धुन के लिए कुछ हमारा काम

मैंने विभिन्न लेख, पोस्ट और इस तरह पढ़ा है और मैं यह देखना चाहता हूं कि किसी के पास कोई ज्ञान है जो हमारी विशिष्ट स्थिति में मदद कर सकता है।

+0

शायद आप vert'x करने का मौका दे सकते हैं? यह बहुत अच्छा async समर्थन – nowszy94

उत्तर

3

जो समस्या आप वर्णन कर रहे हैं वह उस तरह की आवाज नहीं है जिसे आप ब्लॉकिंग आईओ का उपयोग कर रहे हैं तो अच्छी तरह से हल किया जा सकता है। तो आप सही रास्ते पर हैं, क्योंकि DeferredResult आपको सर्वलेट-कंटेनर थ्रेड को अवरुद्ध किए बिना किसी भी थ्रेड का उपयोग करके परिणाम उत्पन्न करने की अनुमति देता है।

एक लंबे पूलिंग एपीआई अपस्ट्रीम को कॉल करने के संबंध में, आपको एक एनआईओ समाधान भी चाहिए। यदि आप नेटी क्लाइंट का उपयोग करते हैं, तो आप एक थ्रेड का उपयोग करके कई हजार सॉकेट प्रबंधित कर सकते हैं। जब नेटटी में एनआईओ चयनकर्ता डेटा का पता लगाता है, तो आपको एक चैनल कॉलबैक मिलेगा और अंत में नेटटी वर्कर थ्रेड पूल में एक थ्रेड पर प्रतिनिधि होगा, और आप deferredResult.setResult पर कॉल कर सकते हैं। यदि आप आईओ को अवरुद्ध नहीं करते हैं तो वर्कर पूल आमतौर पर सीपीयू-कोर की संख्या के बाद आकार दिया जाता है, अन्यथा आपको अधिक धागे की आवश्यकता हो सकती है।

अभी भी कई चुनौतियां हैं।

  • आपको केवल एक से अधिक सर्वर (या नेटवर्क इंटरफेस) की आवश्यकता है क्योंकि केवल 65 के बंदरगाह हैं।
  • जावा में सॉकेट्स में टाइमआउट नहीं हैं, इसलिए यदि कोई ग्राहक सॉकेट से डेटा पढ़ने से इंकार कर देता है, और आप अपने सॉकेट बफर से अधिक डेटा भेजते हैं, तो आप नेटटी वर्कर थ्रेड को अवरुद्ध करेंगे और फिर सब कुछ रुक जाएगा (रिवर्स धीमी लॉरी हमले)। यह बड़े एसिंक सेटअप में क्लासिक समस्या है, और हाइस्ट्रिक्स (नेटफ्लिक्स द्वारा) जैसे ढांचे का उपयोग करने के कारणों में से एक है।
+0

शानदार है, धन्यवाद।यह वही है जो मैं पुष्टि (और उम्मीदवार) वैध दिशा में जारी रखने के लिए पर्याप्त जानकारी के मामले में देख रहा था। – WIllJBD

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