2012-04-02 6 views
7

मुझे यूनिक्स (डेबियन, कर्नेल 2.6.32) में सर्वर प्रोग्रामिंग के बारे में एक बहुत ही विशिष्ट सवाल मिला। मेरा लक्ष्य यह सीखना है कि एक सर्वर कैसे लिखना है जो बड़ी मात्रा में ग्राहकों को संभाल सकता है। मेरा लक्ष्य 30 000 से अधिक समवर्ती ग्राहकों (यहां तक ​​कि जब मेरा कॉलेज उल्लेख करता है कि 500 ​​000 संभव है, जो कि QUIIITEEE एक बड़ी राशि :-) लगता है), लेकिन मुझे वास्तव में पता नहीं है (यहां तक ​​कि क्या संभव है) और इसलिए मैं पूछता हूं यहाँ। तो मेरा पहला सवाल है। कितने एक साथ ग्राहक संभव हैं? ग्राहक जब चाहें कनेक्ट कर सकते हैं और अन्य ग्राहकों के संपर्क में आ सकते हैं और समूह बना सकते हैं (1 समूह में अधिकतम 12 क्लाइंट हैं)। वे एक दूसरे के साथ चैट कर सकते हैं, इसलिए टीसीपी/आईपी पैकेज आकार भेजे गए संदेश के आधार पर भिन्न होता है। ग्राहक भी सर्वर पर गणितीय सूत्र भेज सकते हैं। सर्वर उन्हें हल करेगा और जवाब को समूह में वापस प्रसारित करेगा। यह एक काफी भारी ऑपरेशन है।सी (phtreads, चयन या कांटा?) में लिनक्स सर्वर लिखने के लिए सबसे अच्छा तरीका

मेरा वर्तमान दृष्टिकोण सर्वर को शुरू करना है। एक डेमॉन प्रक्रिया बनाने के लिए कांटा का उपयोग करने से भी। डेमॉन प्रक्रिया सॉकेट fd_listen को बांधती है और सुनना शुरू कर देती है। यह थोड़ी देर (1) पाश है। मैं आने वाली कॉल प्राप्त करने के लिए स्वीकार() का उपयोग करता हूं।

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

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

ठीक है, मुझे लगता है मैं मार्कस कुछ सुझाव देखना चाहते :-)

Groetjes

पी.एस. लगता है मैं इसे सी ++ और सी के लिए टैग करता हूं क्योंकि यह दोनों भाषाओं पर लागू होता है।

+0

मैं थ्रेड पूल के साथ जाऊंगा, इसलिए आपको प्रत्येक कनेक्शन के लिए एक नया धागा बनाने की आवश्यकता नहीं होगी। यह दोनों तेज़ है और अधिकतम 5000 कनेक्शन से बचाता है। –

+1

मैं ग्राहकों को गतिविधि के लिए देखने के लिए एपोल का उपयोग करने का सुझाव देता हूं, और फिर शायद कार्यकर्ता धागे I/O करने के लिए और डेटा के साथ काम करने के लिए। आपको यह उपयोगी मिल सकता है: http://www.kegel.com/c10k.html –

+0

हाँ मेरे पास एक थ्रेड पूल है। इसमें एक बूल is_used और pthread_t thread_id के साथ एक संरचना शामिल है। उस से मैं धागे लाता हूं। –

उत्तर

4

आज के रूप में सबसे अच्छा तरीका एक घटना पाशlibev या libevent की तरह है।

ज्यादातर मामलों में आप पाएंगे कि एक धागा पर्याप्त से अधिक है, लेकिन यदि यह नहीं है, तो भी आप अलग-अलग लूप (कम से कम libev के साथ) के साथ कई धागे रख सकते हैं।

लिबेव [एंट] प्रत्येक ओएस के लिए सबसे कुशल मतदान समाधान का उपयोग करता है (और कुछ भीselect या सॉकेट प्रति थ्रेड से अधिक कुशल है)।

+2

ध्यान दें कि libev एज-ट्रिगर नोटिफिकेशन का समर्थन नहीं करता है (लेकिन एपोल करता है)। –

+0

हाँ, लेकिन जब आपको इसकी आवश्यकता नहीं होती है तो आप ईवेंट को हमेशा अनसेट कर सकते हैं, इसलिए मुझे यह गंभीर समस्या के रूप में नहीं दिखाई देता है। –

+0

किसी भी चीज के साथ आपका क्या मतलब है चुनने से अधिक कुशल है? –

0

मुझे लगता है कि आप इस समस्या को हल करने के लिए इवेंट मॉडल (एपोल + वर्कर थ्रेड पूल) का उपयोग कर सकते हैं। सबसे पहले मुख्य धागे में सुनें और स्वीकार करें, यदि क्लाइंट सर्वर से कनेक्ट होता है, तो मुख्य थ्रेड क्लाइंट_एफडी को एक वर्कर थ्रेड में वितरित करता है, और एपोल सूची जोड़ता है, तो यह कार्यकर्ता थ्रेड क्लाइंट से रिकक्स्ट को संभालेगा।

कार्यकर्ता थ्रेड की संख्या समस्या द्वारा कॉन्फ़िगर किया जा सकता है, और यह अब 5000 नहीं होना चाहिए।

+0

एपोल के बिना, मैं इस समय क्या कर रहा हूं। लेकिन मैं 5000 से अधिक ग्राहकों को संभालना चाहता हूं। तो प्रति ग्राहक एक धागा एक सौदा नहीं है। –

+0

@ मार्कसफंडस्टीन प्रत्येक धागा इस समाधान में कई ग्राहकों को संभालेगा। –

+0

@ मार्कसपंडस्टीन एक धागा कई ग्राहकों को संभाल सकता है, आपको प्रति थ्रेड के लिए एक अनुरोध को संभालने की ज़रूरत नहीं है, और थ्रेड बनाने या धागे को नष्ट करने में समय लगता है। आप nginx उपकरण का संदर्भ दे सकते हैं, जो एक वेब सर्वर है और कार्यकर्ता प्रक्रिया + एपोल का उपयोग करें, और 10 के कोकुरेंट आवश्यकताएं संभाल सकता है। – yaronli

1

आप सीमा के एक जोड़े में चलाने होगी:

  1. fd_set आकार: यह संकलन समय पर अस्थिर है, लेकिन डिफ़ॉल्ट रूप से काफी कम सीमा होती है, इस select समाधान प्रभावित करता है।
  2. थ्रेड-प्रति-सॉकेट बहुत पहले भाप से बाहर चला जाएगा - मैं सुझाव देता हूं कि लंबी धागे में अलग-अलग धागे (यदि आवश्यक हो तो पूलिंग के साथ) डालें, लेकिन अन्यथा एक धागा दृष्टिकोण शायद स्केल करेगा।

500,000 तक पहुंचने के लिए आपको मशीनों का एक सेट और राउंड-रॉबिन डीएनएस संदेह होगा।

टीसीपी पोर्ट एक समस्या नहीं होनी चाहिए, जब तक कि सर्वर ग्राहकों से कनेक्शन न करे। मैं हमेशा इसे भूल जाता हूं, और याद दिलाना होगा।

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

+0

1. नहीं, सर्वर पर केवल एक बंदरगाह है। –

+0

@ करोलि प्रत्येक कनेक्शन को एक बंदरगाह की आवश्यकता होती है। कनेक्शन बनाने के लिए एक बंदरगाह का उपयोग किया जाता है, जिसके बाद, ओएस आगे संचार के लिए ऊपरी सीमा में एक यादृच्छिक बंदरगाह निर्दिष्ट करता है। – Ioan

+0

मैंने टीसीपी पोर्ट समस्या के बारे में नहीं सोचा था। इसका जिक्र करने के लिए उपरोक्त। मेरा लक्ष्य 30 000 है इसलिए इसका आधा रास्ते है। –

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