2011-11-16 13 views
8

मैंने रूबी और रेल के विभिन्न संस्करणों में थ्रेड सुरक्षा और प्रदर्शन के बारे में वेब के चारों ओर बहुत सारी सामग्री पढ़ी है और मुझे लगता है कि मैं इस बिंदु पर उन चीजों को काफी अच्छी तरह समझता हूं।थ्रेडसेफ एसिंक्रोनस रेल ऐप को कैसे तैनात करें?

चर्चाओं से अजीब रूप से गायब होने की प्रतीत होती है कि वास्तव में एक एसिंक्रोनस रेल ऐप को कैसे तैनात करना है। जब धागे और किसी ऐप में समक्रमिकता बारे में बात कर, दो चीजें लोगों को अनुकूलित करना चाहते हैं:

  1. न्यूनतम RAM उपयोग
  2. नया अनुरोध का उत्तर देने के लिए सक्षम होने के साथ सभी सीपीयू कोर का उपयोग करते हुए पिछले अनुरोध आईओ
  3. पर इंतजार कर रहे हैं

प्वाइंट 1 वह जगह है जहां लोग जेआरबी के बारे में उत्साहित होते हैं।

TheController < ActionController::Base 
    def fast 
    render :text => "hello" 
    end 

    def slow 
    render :text => User.count.to_s 
    end 
end 

fast कोई आईओ है और सैकड़ों या अनुरोध प्रति सेकंड के हजारों सेवा कर सकते हैं, और slow: इस सवाल के लिए मैं केवल बिंदु अनुकूलन करने के लिए 2.

इस मेरे एप्लिकेशन में केवल नियंत्रक है कहो कोशिश कर रहा हूँ नेटवर्क पर एक अनुरोध भेजना है, काम करने की प्रतीक्षा करें, फिर नेटवर्क पर जवाब प्राप्त करें, और इसलिए fast से बहुत धीमी है।

तो एक आदर्श परिनियोजन सैकड़ों अनुरोधों को fast को पूरा करने की अनुमति देगा जबकि slow पर अनुरोध IO पर प्रतीक्षा कर रहा है।

वेब के आसपास की चर्चाओं से क्या गुम हो रहा है यह है कि इस समेकन को सक्षम करने के लिए ढेर की कौन सी परत जिम्मेदार है। पतली में --threaded ध्वज है, जो "थ्रेड [प्रयोगात्मक] में रैक एप्लिकेशन को कॉल करेगा" - क्या यह प्रत्येक आने वाले अनुरोध के लिए एक नया धागा शुरू करता है? थ्रेड में रैक ऐप उदाहरणों को स्पूल करें जो आने वाले अनुरोधों के लिए बने रहें और प्रतीक्षा करें?

क्या पतला एकमात्र तरीका है या अन्य लोग हैं? क्या रूबी रनटाइम प्वाइंट 2 को अनुकूलित करने के लिए मायने रखता है?

+0

मुझे संदेह होगा कि आपके रूबी संस्करण के बिंदु 2 के संबंध में बहुत कुछ कहना होगा। यह सर्वर के समवर्ती कार्यान्वयन पर निर्भर करेगा और कैसे रेल स्वयं को एक साथ रखा जाएगा। – providence

उत्तर

6

आपके लिए सही दृष्टिकोण आपके slow विधि पर निर्भर करता है।

एक परिपूर्ण दुनिया में, आप फाइबर में प्रत्येक अनुरोध को संभालने के लिए sinatra-synchrony मणि जैसे कुछ उपयोग का उपयोग कर सकते हैं। आप केवल तंतुओं की अधिकतम संख्या से ही सीमित होंगे। दुर्भाग्य से, फाइबर पर स्टैक आकार hardcoded है, और रेल ऐप में ओवरराउन करना आसान है। इसके अतिरिक्त, मैंने डीबगिंग फाइबर की कठिनाइयों की कुछ डरावनी कहानियां पढ़ी हैं, क्योंकि एसिंक आईओ शुरू होने के बाद स्वचालित उपज के कारण। तंतुओं का उपयोग करते समय भी रेस की स्थिति अभी भी संभव है। वर्तमान में, फाइबर रूबी कम से कम एक वेब ऐप के सामने के अंत में एक यहूदी बस्ती है।

एक और व्यावहारिक समाधान जिसमें कोड परिवर्तन की आवश्यकता नहीं है, वह रैक सर्वर का उपयोग करना है जिसमें वर्कबॉज थ्रेड जैसे पूल हैं! या प्यूमा। मेरा मानना ​​है कि थिन का --threaded ध्वज प्रत्येक अनुरोध को नए थ्रेड में संभालता है, लेकिन मूल ओएस थ्रेड को कताई करना सस्ता नहीं है। पर्याप्त आकार के पूल आकार के साथ एक थ्रेड पूल का उपयोग करने के लिए बेहतर है। रेल में, उत्पादन में config.threadsafe! सेट करना न भूलें।

यदि आप कोड बदलने के साथ ठीक हैं, तो आप Konstantin Haase के उत्कृष्ट talk on real-time Rack देख सकते हैं। उन्होंने EventMachine::Deferrable वर्ग का उपयोग पारंपरिक अनुरोध/प्रतिक्रिया चक्र के बाहर प्रतिक्रिया उत्पन्न करने के लिए किया है जो रैक पर बनाया गया है। यह वास्तव में साफ दिखता है, लेकिन आपको कोड को एसिंक शैली में फिर से लिखना होगा।

Cramp और Goliath पर भी एक नज़र डालें। ये आपको अपने रेल ऐप के साथ होस्ट किए गए एक अलग रैक ऐप में slow विधि को लागू करने देते हैं, लेकिन आपको शायद क्रैम्प/गोलीथ हैंडलर में काम करने के लिए अपने कोड को फिर से लिखना होगा।

रुबी रनटाइम के बारे में आपके प्रश्न के लिए, यह उस काम पर निर्भर करता है जो slow कर रहा है। यदि आप सीपीयू-भारी गणना कर रहे हैं, तो आप जीआईएल के जोखिम को आपको समस्याएं देते हैं। यदि आप आईओ कर रहे हैं, तो जीआईएल आपके रास्ते में नहीं होना चाहिए। (मुझे नहीं कहना चाहिए क्योंकि मुझे विश्वास है कि मैंने जीआईएल को अवरुद्ध करने वाले पुराने माइस्क्ल मणि के साथ मुद्दों के बारे में पढ़ा है।)

व्यक्तिगत रूप से, मुझे बैकएंड, मैशप वेब सेवा के लिए साइनेट्रा-सिंक्रनाइज़ का उपयोग करके सफलता मिली है। मैं समानांतर में बाहरी वेब सेवाओं के लिए कई अनुरोध जारी कर सकता हूं, और उन सभी को वापस लौटने का इंतजार कर सकता हूं। इस बीच, फ्रंटेंड रेल सर्वर एक थ्रेड पूल का उपयोग करता है, और बैकएंड को सीधे अनुरोध करता है। सही नहीं है, लेकिन यह अभी ठीक से काम करता है।

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