2011-08-15 14 views
35

मैं रैक में समवर्ती अनुरोध हैंडलिंग के विकल्पों को पूरी तरह से समझने का प्रयास कर रहा हूं। मैंने एक लंबे मतदान वाले ऐप बनाने के लिए async_sinatra का उपयोग किया है, और अब throw :async और/या पतला - थ्रेड वाला ध्वज का उपयोग करके नंगे धातु रैक के साथ प्रयोग कर रहा हूं। मैं इस विषय के साथ सहज हूं, लेकिन कुछ चीजें हैं जिन्हें मैं समझ नहीं पा रहा हूं। (नहीं, मैं समांतरता के लिए समवर्तीता को गलत नहीं समझ रहा हूं, और हां, मैं जीआईएल द्वारा लगाई गई सीमाओं को समझता हूं)।रैक समवर्ती - rack.multithread, async.callback, या दोनों?

क्यू 1। मेरे परीक्षण इंगित करते हैं कि thin --threaded (यानी rack.multithread=true) अलग-अलग धागे (मैं ईएम का उपयोग करना मानता हूं) में समवर्ती रूप से अनुरोध करता हूं, जिसका अर्थ है लंबे समय से चलने वाला अनुरोध ए अनुरोध बी (आईओ को अलग) को अवरुद्ध नहीं करेगा। इसका मतलब है कि मेरे आवेदन को समेकन प्राप्त करने के लिए किसी भी विशेष कोडिंग (उदा। कॉलबैक) की आवश्यकता नहीं है (फिर, ब्लॉकिंग डीबी कॉल, आईओ इत्यादि को अनदेखा करना)। यही मेरा मानना ​​है कि मैंने देखा है - क्या यह सही है?

प्रश्न 2। EventMachine.defer और throw :async समेत समवर्तीता प्राप्त करने के एक और अधिक चर्चा किए गए माध्यम हैं। कड़ाई से बोलते हुए, अनुरोध धागे का उपयोग करके संभाले गए हैं। उन्हें क्रमशः निपटाया जाता है, लेकिन इन्हें भारी उठाने और इवेंटमैचिन को कॉलबैक बंद कर दिया जाता है, जो बाद में प्रतिक्रिया भेजने के लिए async.callback का उपयोग करता है। अनुरोध के बाद ए ने अपना काम EM.defer पर ऑफ़लोड कर दिया है, अनुरोध बी शुरू हो गया है। क्या यह सही है?

क्यू 3। उपर्युक्त मानना ​​अधिक या कम सही है, क्या दूसरे पर एक विधि के लिए कोई विशेष लाभ है? जाहिर है --threaded एक जादू बुलेट की तरह दिखता है। क्या कोई डाउनसाइड्स हैं? यदि नहीं, तो हर कोई async_sinatra/throw :async/async.callback के बारे में क्यों बात कर रहा है? शायद पूर्व "मैं अपने रेल ऐप को भारी भार के तहत थोड़ा सा स्नैपियर बनाना चाहता हूं" और बाद वाले कई लंबे समय से चल रहे अनुरोधों वाले ऐप्स के लिए बेहतर अनुकूल है? या शायद पैमाने एक कारक है? बस अनुमान लगाओ।

मैं एमआरआई रूबी 1.9.2 पर पतला 1.2.11 चला रहा हूं। (FYI करें, मैं --no-epoll झंडा उपयोग करने के लिए, के रूप में वहाँ epoll और रूबी 1.9.2 के EventMachine के उपयोग के साथ a long-standing, supposedly-resolved-but-not-really problem है है कि बिंदु के पास है, लेकिन किसी भी अंतर्दृष्टि का स्वागत है।।)

+0

एपोल समस्या को ठीक किया जाना चाहिए क्योंकि यह उस टिकट में कहता है, यह [प्रतिबद्धता] है (https://github.com/eventmachine/eventmachine/commit/d684cc3b77a6c401295a3086b5671fe4ec335a64) वे इंगित कर रहे हैं। – Bitterzoet

+0

यदि मैं --no-epoll ध्वज को हटाता हूं तो मेरे थ्रेडेड अनुरोध मिलीसेकंड से मिनट तक जाते हैं। ईएम 0.12.10, रुबी 1.9.2-पी 180। मुझे लगता है कि मैं पी 2 9 0 संकलित करने की कोशिश कर सकता हूं ... – bioneuralnet

+0

अच्छा सवाल। मैंने यहां एक बहुत ही समान प्रश्न पूछा है: http://stackoverflow.com/questions/8146851/how-to-deploy-a-threadsafe-asynchronous-rails-app और यहां कुछ प्रयोग किया है: https: // github। कॉम/जेजेबी/थ्रेडेड-रेल-उदाहरण (ध्यान दें कि थ्रेडेड पतले सफलतापूर्वक असीमित है, यह बेंचमार्क धीमा है) –

उत्तर

24

नोट: मैं सभी के लिए पर्याय के रूप में पतला का उपयोग एसिंक रैक एक्सटेंशन (यानी इंद्रधनुष !, ईबीबी, प्यूमा के भविष्य के संस्करणों को लागू करने वाले वेब सर्वर ...)

प्रश्न 1। सही। यह EventMachine.defer { ... } में प्रतिक्रिया पीढ़ी (उर्फ call) लपेट जाएगा, जिससे इवेंटमैचिन इसे अपने अंतर्निर्मित थ्रेड पूल पर धक्का देगी।

प्रश्न 2। का उपयोगके साथ संयोजन में वास्तव में बहुत अधिक समझ में नहीं आता है, क्योंकि यह मूल रूप से थ्रेड-पूल का उपयोग करेगा, क्यू 1 में वर्णित एक समान निर्माण के साथ समाप्त होता है। async.callback का उपयोग करना केवल आईओ के लिए इवेंटमाचिन लाइब्रेरी का उपयोग करते समय समझ में आता है। env['async.callback'] को तर्क के रूप में सामान्य रैक प्रतिक्रिया के साथ बुलाया जाता है, तो ग्राहक ग्राहक को प्रतिक्रिया भेज देगा।

यदि शरीर EM::Deferrable है, तो थिन उस कनेक्शन को तब तक बंद नहीं करेगा जब तक कि डिफ्रैबल सफल नहीं हो जाता। एक बेहतर रखा गया गुप्त: यदि आप केवल लंबे मतदान से अधिक चाहते हैं (यानी आंशिक प्रतिक्रिया भेजने के बाद कनेक्शन को खोलें), तो आप को throw :async या -1 का स्टेटस कोड उपयोग किए बिना सीधे बॉडी ऑब्जेक्ट के रूप में वापस कर सकते हैं।

क्यू 3। आप सही अनुमान लगा रहे हैं। थ्रेडेड सेवारत अन्यथा अपरिवर्तित रैक एप्लिकेशन पर लोड को बेहतर बना सकता है। मुझे रुबी 1.9.3 के साथ मेरी मशीन पर सरल सिनात्रा अनुप्रयोगों के लिए 20% सुधार दिखाई देता है, रूबिनीस या जेआरबी पर चलते समय भी, जहां सभी कोर का उपयोग किया जा सकता है। दूसरा दृष्टिकोण उपयोगी है यदि आप अपना आवेदन किसी तरीके से लिखते हैं।

आप रैक के शीर्ष पर बहुत सारे जादू और हैक्स फेंक सकते हैं ताकि एक गैर-घटनाबद्ध अनुप्रयोग उन तंत्रों का उपयोग कर सके (एम-सिंक्रोन या सिनात्रा-सिंक्रनाइज़ देखें), लेकिन यह आपको डिबगिंग और निर्भरता नरक में छोड़ देगा ।

एसिंक दृष्टिकोण उन अनुप्रयोगों के साथ वास्तविक ज्ञान बनाता है जो a web chat जैसे किसी ईवेंट के साथ सबसे अच्छा हल किया जाता है। हालांकि, मैं लंबी मतदान को लागू करने के लिए थ्रेडेड दृष्टिकोण का उपयोग करने की अनुशंसा नहीं करता, क्योंकि प्रत्येक मतदान कनेक्शन थ्रेड को अवरुद्ध कर देगा। यह आपको धागे या कनेक्शन के एक टन के साथ छोड़ देगा जो आप सौदा नहीं कर सकते हैं। ईएम के थ्रेड पूल में डिफ़ॉल्ट रूप से 20 धागे का आकार होता है, जो आपको प्रति प्रक्रिया 20 प्रतीक्षा कनेक्शन तक सीमित करता है।

आप ऐसे सर्वर का उपयोग कर सकते हैं जो प्रत्येक आने वाले कनेक्शन के लिए एक नया धागा बनाता है, लेकिन धागे बनाना महंगा है (मैक्रूबी को छोड़कर, लेकिन मैं किसी भी उत्पादन ऐप में मैक्रूबी का उपयोग नहीं करता)। उदाहरण serv और net-http-server हैं। आदर्श रूप में, आप जो चाहते हैं वह अनुरोध है और धागे का एम मैपिंग है। लेकिन वहां कोई सर्वर नहीं है।

यदि आप इस विषय पर अधिक जानना चाहते हैं: मैंने रॉकी माउंटेन रूबी (और अन्य सम्मेलनों का एक टन) में इसके बारे में एक प्रस्तुति दी। एक वीडियो रिकॉर्डिंग on confreaks पाया जा सकता है।

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