कई ब्लॉकिंग वीएस सिंगल नॉन-ब्लॉकिंग वर्कर्स


9

मान लें कि एक HTTP सर्वर है जो कनेक्शन स्वीकार करता है और फिर उसने किसी तरह हेडर के पूरी तरह से भेजे जाने की प्रतीक्षा की है। मुझे आश्चर्य है कि इसे लागू करने का सबसे आम तरीका क्या है और बाकी पेशेवरों और विपक्ष क्या हैं। मैं केवल इन के बारे में सोच सकता हूं:

कई अवरुद्ध श्रमिक अच्छे हैं क्योंकि:

  • यह अधिक उत्तरदायी है।
  • नए कनेक्शन शुरू करने के लिए आसान (कार्यकर्ता उन्हें बाहरी व्यक्ति के बजाय खुद को उठाते हैं जब तक कि यह एक सिंक्रनाइज़ सूची में जोड़ नहीं सकता)।
  • कनेक्शनों की संख्या बढ़ने और घटने के साथ ही CPU उपयोग अपने आप (बिना किसी अतिरिक्त प्रयास के) शेष हो जाता है।
  • कम सीपीयू उपयोग (अवरुद्ध धागे निष्पादन लूप से बाहर ले जाया जाता है और ग्राहकों के बीच कूदने के लिए किसी भी तर्क की आवश्यकता नहीं होती है)।

एकल गैर-अवरुद्ध कार्यकर्ता अच्छा है क्योंकि:

  • कम मेमोरी का उपयोग करता है।
  • आलसी ग्राहकों के लिए कम संवेदनशील (जो सर्वर से जुड़ते हैं और हेडर धीरे भेजते हैं या बिल्कुल नहीं भेजते हैं)।

जैसा कि आप शायद देख सकते हैं, मेरी राय में कई कार्यकर्ता-सूत्र समग्र रूप से थोड़ा बेहतर समाधान हैं। इसके साथ एकमात्र समस्या यह है कि ऐसे सर्वर पर हमला करना आसान है।

संपादित करें (अधिक शोध): कुछ संसाधन जो मुझे वेब ( थ्रेड्स और ब्लॉकिंग आई / ओ - वेब पर मिले हैं - जावा सर्वर को लिखने का पुराना तरीका पॉल फिर से नया है (और बेहतर तरीके से ) संकेत है कि ब्लॉकिंग दृष्टिकोण आम तौर पर बेहतर है लेकिन मुझे अभी भी नहीं पता है कि नकली कनेक्शन से कैसे निपटना है।

PS कार्य के लिए कुछ लाइब्रेरी या एप्लिकेशन का उपयोग करने का सुझाव नहीं देते हैं। मुझे यह जानने में अधिक दिलचस्पी है कि यह वास्तव में कैसे काम करता है या काम करने के बजाय काम कर सकता है।

PSS मेरे पास कई भागों में विभाजित तर्क हैं और यह केवल HTTP हेडर स्वीकार करने का काम करता है। उन्हें संसाधित नहीं करता है।


लो, ये कई साल पहले, मैंने I / O को अवरुद्ध करने के साथ एक थ्रेडेड सर्वर लिखा था, क्योंकि इसे लिखना आसान था। एक सहकर्मी ने दूसरी तरह की बात लिखी और इसने सराहनीय ढंग से काम किया। वे एक कंपनी में काम करने वाले प्रमुख उत्पाद की पेशकश के दो रूप थे। अवरुद्ध परिदृश्य में "आलसी क्लाइंट" के लिए आप डेटा रिसेप्शन पर टाइमआउट कर सकते हैं।

जवाबों:


4

कोई चांदी की गोली नहीं है

व्यवहार में यह निर्भर करता है ...

tl; dr - आसान उपाय, nginx का उपयोग करें ...

ब्लॉक करना:

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

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

AFAIK, एक अवरुद्ध HTTP सर्वर पर एक बहु-प्रक्रिया दृष्टिकोण का उपयोग करना आमतौर पर पसंद किया जाता है क्योंकि यह सुरक्षित तरीके से स्मृति को प्रबंधित / पुनर्प्राप्त करने के लिए सुरक्षित / सरल है। स्मृति को पुनर्प्राप्त करने के दौरान कचरा संग्रह एक गैर-मुद्दा बन जाता है, जो एक प्रक्रिया को रोकने के रूप में सरल है। लंबे समय तक चलने वाली प्रक्रियाओं (यानी एक डेमन) के लिए जो कि विशेषता विशेष रूप से महत्वपूर्ण है।

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

जहाँ सर्वर जो अवरोधक का उपयोग करते हैं वे IO भारी भार के लिए आदर्श विकल्प नहीं हो सकते हैं, वे सीपीयू-सघन कार्य के लिए आदर्श हैं और संदेश पासिंग को एक माइनम में रखा जाता है।

गैर-अवरुद्ध:

नॉन-ब्लॉकिंग Node.js या nginx जैसा कुछ होगा। ये विशेष रूप से IO- गहन भार के तहत नोड प्रति कनेक्शन की एक बड़ी संख्या को स्केलिंग के लिए जाना जाता है। मूल रूप से, एक बार लोगों ने ऊपरी सीमा को मारा था कि वैकल्पिक विकल्पों का पता लगाने के लिए थ्रेड / प्रक्रिया-आधारित सर्वर क्या संभाल सकते हैं। इसे अन्यथा C10K समस्या (यानी 10,000 समवर्ती कनेक्शन को संभालने की क्षमता) के रूप में जाना जाता है ।

नॉन-ब्लॉकिंग एसिंक्स सर्वर आम तौर पर मल्टी-थ्रेडेड-विथ-लॉकिंग दृष्टिकोण के साथ बहुत सारी विशेषताओं को साझा करता है जिसमें आपको सीपीयू-गहन भार से बचने के लिए सावधान रहना होगा क्योंकि आप मुख्य धागे को अधिभार नहीं देना चाहते हैं। लाभ यह है कि संदर्भ स्विचिंग द्वारा किए गए ओवरहेड को अनिवार्य रूप से समाप्त कर दिया जाता है और केवल एक संदर्भ संदेश गुजरने के साथ एक गैर-मुद्दा बन जाता है।

हालांकि यह कई नेटवर्किंग प्रोटोकॉल के लिए काम नहीं कर सकता है, HTTPs स्टेटलेस प्रकृति विशेष रूप से अच्छी तरह से गैर-अवरुद्ध आर्किटेक्चर के लिए काम करती है। रिवर्स-प्रॉक्सी और मल्टीपल नॉन-ब्लॉकिंग एचटीटीपी सर्वर के संयोजन का उपयोग करके भारी लोड का सामना करने वाले नोड्स के आसपास की पहचान करना और उन्हें रूट करना संभव है।

यहां तक ​​कि एक सर्वर पर जिसमें केवल एक नोड होता है, सेटअप के लिए प्रति प्रोसेसर कोर में एक सर्वर को शामिल करने के लिए थ्रूपुट को अधिकतम करना बहुत आम है।

दोनों:

'आदर्श' उपयोग मामला दोनों का संयोजन होगा। शीर्ष पर रूटिंग अनुरोधों के लिए समर्पित मोर्चे पर एक रिवर्स प्रॉक्सी, फिर अवरुद्ध और गैर-अवरुद्ध सर्वर का मिश्रण। स्थिर सामग्री, कैश सामग्री, HTML सामग्री की सेवा जैसे IO कार्यों के लिए गैर-अवरोधक। सीपीयू-भारी कार्यों के लिए ब्लॉक करना जैसे कि इमेजेज / वीडियो, स्ट्रीमिंग कंटेंट, नंबर क्रंचिंग, डेटाबेस राइट्स आदि।

आपके मामले में:

यदि आप केवल हेडर चेक कर रहे हैं, लेकिन वास्तव में अनुरोधों को संसाधित नहीं कर रहे हैं, तो आप जो अनिवार्य रूप से वर्णन कर रहे हैं वह रिवर्स प्रॉक्सी है। ऐसे मामले में मैं निश्चित रूप से एक async दृष्टिकोण के साथ जाना होगा।

मेरा सुझाव है कि nginx में निर्मित रिवर्स प्रॉक्सी के लिए प्रलेखन की जाँच करें ।

एक तरफ:

मैंने आपके द्वारा दिए गए लिंक से राइट-अप पढ़ा और यह समझ में आता है कि async उनके विशेष कार्यान्वयन के लिए एक खराब विकल्प था। एक बयान में इस मुद्दे को संक्षेप में प्रस्तुत किया जा सकता है।

पाया कि ग्राहकों के बीच स्विच करते समय, मूल्यों / स्थिति को बचाने और पुनर्स्थापित करने के लिए कोड मुश्किल था

वे एक राज्य-पूर्ण मंच का निर्माण कर रहे थे। इस तरह के मामले में, एक एसिंक्स दृष्टिकोण का मतलब होगा कि आपको हर बार संदर्भ स्विच (यानी जब कोई घटना होती है) राज्य को बचाने / लोड करना होगा। इसके अलावा, SMTP की तरफ वे बहुत सारे CPU-गहन कार्य कर रहे हैं।

ऐसा लगता है कि वे async के एक बहुत गरीब समझ था और परिणामस्वरूप, बहुत बुरा अनुमान लगाया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.