उत्पादन में गिरावट, रैम मुक्त होने पर CPU, 100%, सीपीयू, मोंगोडब, रेडिस


11

जैसा कि प्रश्न शीर्षक से पता चलता है, मुझे एक स्वीकार्य प्रदर्शन प्राप्त करने के लिए यह जानने के लिए एक कठिन समय है कि मेरे आवेदन में क्या सुधार किया जा सकता है (या ओएस, ऑबंटू में ट्यून किया गया है)। लेकिन पहले मैं वास्तुकला की व्याख्या करूँगा:

फ्रंट-एंड सर्वर 8 कोर मशीन है जिसमें 8 गीगा रैम उबंटू 12.04 चल रहा है। एप्लिकेशन को पूरी तरह से जावास्क्रिप्ट में लिखा गया है और नोड.जेएस वी 0.8.22 में चला जाता है (जैसा कि कुछ मॉड्यूल नोड के नए संस्करणों पर शिकायत करते हैं) मैं पोर्ट 80 और 443 से 8 नोड श्रमिकों के लिए प्रॉक्सी HTTP ट्रैफ़िक में nginx 1.4 का उपयोग करता हूं जो प्रबंधित हैं और नोड क्लस्टर एपीआई का उपयोग शुरू कर दिया। मैं वेबसैट कनेक्शन को संभालने के लिए सॉकेट.आईओ 0.9.14 के नवीनतम संस्करण का उपयोग करता हूं, जिस पर मैंने केवल वेबसैकेट और xhr-polling को उपलब्ध ट्रांसपोर्ट के रूप में सक्षम किया है। इस मशीन पर मैं रेडिस (2.2) का एक उदाहरण भी चलाता हूं

मैं 4g RAM और 2 कोर के साथ mongodb (3.6) पर एक दूसरे सर्वर पर लगातार डेटा (जैसे उपयोगकर्ता और स्कोर) संग्रहीत करता हूं।

एप्लिकेशन कुछ महीनों से उत्पादन में है (यह कुछ सप्ताह पहले तक एक ही बॉक्स पर चल रहा है) और इसे प्रति दिन लगभग 18k उपयोगकर्ताओं द्वारा उपयोग किया जा रहा है। यह हमेशा एक मुख्य मुद्दे के अलावा बहुत अच्छी तरह से काम करता है: प्रदर्शन में गिरावट। उपयोग के साथ, प्रत्येक प्रक्रिया द्वारा उपयोग किए जाने वाले सीपीयू की मात्रा तब तक बढ़ती है, जब तक कि यह कार्यकर्ता (जो अब और अनुरोधों की सेवा नहीं करेगा) को स्थिर करता है। मैंने अस्थायी रूप से इसे हल कर दिया है कि प्रत्येक कार्यकर्ता द्वारा उपयोग में आने वाले सीपीयू की जाँच हर मिनट में की जाती है, और यदि यह 98% तक पहुँच जाता है तो इसे फिर से शुरू किया जाता है। तो यहाँ समस्या मुख्य रूप से सीपीयू है, न कि रैम। RAM एक मुद्दा नहीं है क्योंकि मैंने सॉकेट के लिए अपडेट किया है। 0.9.14 (पहले का संस्करण मेमोरी लीक कर रहा था) इसलिए मुझे संदेह है कि यह एक मेमोरी लीकिंग मुद्दा है, खासकर क्योंकि अब यह सीपीयू है जो काफी तेज़ी से बढ़ता है ( मुझे प्रत्येक कार्यकर्ता को एक दिन में लगभग 10-12 बार पुनरारंभ करना होगा!)। उपयोग में रैम ईमानदार होने के साथ-साथ बढ़ती है, लेकिन बहुत धीरे-धीरे, उपयोग के हर 2-3 दिनों में 1 टमटम, और अजीब बात यह है कि यह तब भी जारी नहीं किया जाता है जब मैं पूरी तरह से पूरी तरह से आवेदन को पुनरारंभ करता हूं। यह केवल तभी जारी किया जाता है जब मैं सर्वर को रिबूट करता हूं! यह मैं वास्तव में नहीं समझ सकता ...

मैंने अब नोडफ़्ले की खोज की है जो आश्चर्यजनक है, इसलिए मैं अंत में देख सकता हूं कि मेरे उत्पादन सर्वर पर क्या हो रहा है, और मैं कुछ दिनों से डेटा एकत्र कर रहा हूं। यदि कोई चार्ट देखना चाहता है तो मैं आपको एक्सेस दे सकता हूं, लेकिन मूल रूप से मैं देख सकता हूं कि मेरे पास 80 और 200 समवर्ती कनेक्शन हैं! मैं हजारों अनुरोधों को संभालने के लिए नोड.जेएस की उम्मीद कर रहा था, सैकड़ों नहीं। साथ ही http ट्रैफ़िक के लिए औसत प्रतिक्रिया समय 500 और 1500 मिलीसेकंड के बीच तैरता है जो मुझे लगता है कि वास्तव में बहुत कुछ है। इसके अलावा, ऑनलाइन 1300 उपयोगकर्ताओं के साथ इस क्षण में, यह "ss -s" का आउटपुट है:

Total: 5013 (kernel 5533)
TCP:   8047 (estab 4788, closed 3097, orphaned 139, synrecv 0, timewait 3097/0), ports 0

Transport Total     IP        IPv6
*         5533      -         -
RAW       0         0         0
UDP       0         0         0
TCP       4950      4948      2
INET      4950      4948      2
FRAG      0         0         0

जो दिखाता है कि मुझे टाइमवेइट में बहुत सारे बंद कनेक्शन मिले हैं। मैंने अधिकतम खुली फ़ाइलों को 999999 तक बढ़ा दिया है, यहाँ ulimit -a का आउटपुट है:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 63724
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 999999
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63724
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

इसलिए मुझे लगा कि समस्या http ट्रैफ़िक पर हो सकती है कि कुछ कारणों से उपलब्ध पोर्ट / सॉकेट्स (?) को संतृप्त करता है, लेकिन एक बात मुझे समझ में नहीं आती है: जब मैं श्रमिकों को फिर से शुरू करता हूं, और सभी ग्राहक कुछ सेकंड के भीतर पुन: कनेक्ट हो जाते हैं, श्रमिक के सीपीयू पर लोड 1% तक कम हो जाता है और लगभग 1 घंटे (पीक समय पर) के बाद संतृप्त होने तक अनुरोधों को ठीक से सेवा करने में सक्षम है?

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

उम्मीद है कि कुछ स्पष्ट है कि मैं गलत कर रहा हूं, और कोई इसे स्पॉट करने में मदद करेगा ... मुझे और अधिक जानकारी के लिए पूछने के लिए स्वतंत्र महसूस हो रहा है, और मुझे प्रश्न की लंबाई के लिए खेद है, लेकिन मुझे विश्वास था कि ... अग्रिम में धन्यवाद!


क्या नोड.जेएस से थ्रेड डंप जैसा कुछ प्राप्त करने का कोई तरीका है? शायद अनंत लूप में कुछ धागे हैं। इसके अलावा, वास्तव में सीपीयू का उपयोग क्या है? topजब सीपीयू का उपयोग 100% के करीब हो तो आप क्या देखते हैं ?
आरवी

सीपीयू का उपयोग पूरी तरह से नोडज द्वारा किया जाता है, जब मैं शीर्ष पर चलता हूं तो मैं सभी सीपीयू लेने वाली नोड प्रक्रियाओं को देखता हूं। मुझे यकीन नहीं है कि मैं कैसे ईमानदार होने के लिए नोड से थ्रेड डंप का उत्पादन कर सकता हूं ...
फ्रैंजेंको

एक और बात यह है कि सीपीयू समय का अधिकांश हिस्सा सिस्टम में जाता है, उपयोगकर्ता समय पर नहीं
फ्रैंजेंको

क्या किसी को कम से कम पता है कि मुझे अपने सर्वर से कितने समवर्ती कनेक्शनों को संभालना चाहिए था? फिलहाल मैं 200 समवर्ती कनेक्शन का समर्थन करता हूं। यह मुझे अनुमान लगाने में मदद करेगा कि मैं एक इष्टतम कॉन्फ़िगरेशन से कितनी दूर हूं ... धन्यवाद।
फ्रांजको

जवाबों:


10

कुछ दिनों के गहन परीक्षण और त्रुटियों के बाद, मुझे यह कहने में खुशी हो रही है कि मैं समझ गया हूं कि अड़चन कहां थी, और मैं इसे यहां पोस्ट करूंगा ताकि अन्य लोग मेरे निष्कर्षों से लाभान्वित हो सकें।

समस्या पब / उप कनेक्शनों में निहित है जो मैं सॉकेट.आईओ के साथ उपयोग कर रहा था, और विशेष रूप से सॉकेट इंस्टेंस के अंतर-प्रक्रिया संचार को संभालने के लिए सॉकेट.आईओ द्वारा उपयोग किए जाने वाले RedisStore में।

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

प्रारंभ में मैंने हर जुड़े ग्राहक पर पब / उप को संभालने के लिए केवल 2 वैश्विक रेडिस कनेक्शन एक्स प्रक्रिया की घोषणा की, और एप्लिकेशन कम पुनरावृत्ति का उपयोग कर रहा था, लेकिन मैं अभी भी लगातार सीपीयू उपयोग वृद्धि से प्रभावित हो रहा था, इसलिए बहुत कुछ नहीं बदला था। लेकिन फिर मैंने प्रत्येक ग्राहक के लिए उनके सत्रों पर केवल पब / सब को संभालने के लिए 2 नए कनेक्शन बनाने की कोशिश करने का फैसला किया, फिर उपयोगकर्ता द्वारा डिस्कनेक्ट होने के बाद कनेक्शन बंद कर दें। फिर उत्पादन में उपयोग के एक दिन बाद, सीपीयू अभी भी 0-5% पर थे ... बिंगो! कोई भी प्रक्रिया पुनरारंभ नहीं होती, कोई बग नहीं, प्रदर्शन के साथ मैं उम्मीद कर रहा था। अब मैं कह सकता हूं कि नोड.जेएस चट्टानें और इस ऐप के निर्माण के लिए इसे चुनने से खुश हूं।

सौभाग्य से रेडिस को कई समवर्ती कनेक्शन (मोंगो द्वारा अलग-अलग) को संभालने के लिए डिज़ाइन किया गया है और डिफ़ॉल्ट रूप से इसे 10k पर सेट किया गया है, जो लगभग 5k समवर्ती उपयोगकर्ताओं के लिए एक ही रेडिस उदाहरण पर छोड़ता है, जो मेरे लिए पल के लिए पर्याप्त है, लेकिन मैं ' मैंने पढ़ा है कि इसे 64k समवर्ती कनेक्शन तक धकेल दिया जा सकता है, इसलिए यह वास्तुकला पर्याप्त रूप से ठोस होनी चाहिए जो मुझे विश्वास है।

इस बिंदु पर मैं कुछ प्रकार के कनेक्शन पूल को फिर से लागू करने के लिए सोच रहा था, इसे थोड़ा आगे अनुकूलित करने के लिए, लेकिन यह सुनिश्चित नहीं है कि कनेक्शन पर निर्माण करने के लिए फिर से पब / उप घटनाओं का कारण नहीं होगा, जब तक कि उनमें से प्रत्येक। हर बार उन्हें नष्ट करने के लिए नष्ट कर दिया जाता है।

वैसे भी, आपके उत्तर के लिए धन्यवाद, और मुझे यह जानने के लिए उत्सुक होना चाहिए कि आप क्या सोचते हैं, और यदि आपके पास कोई अन्य सुझाव है।

चीयर्स।


2
मुझे लगता है कि मेरे उत्पादन ऐप में वही समस्या है, जो सर्वर व्यवस्थापक की भूमिका के लिए भी नई है। मैं उस अवधारणा का पालन करता हूं जो आपने अवधारणा में किया था, लेकिन मेरे पास कुछ प्रश्न हैं कि इसे कैसे किया जाए - शायद आप अपने स्वीकृत उत्तर में कुछ संसाधन का लिंक प्रदान कर सकते हैं? या अधिक जानकारी प्रदान करें? विशेष रूप से "लेकिन फिर मैंने प्रत्येक ग्राहक के लिए अपने सत्रों पर अपने पब / उप को संभालने के लिए 2 नए कनेक्शन बनाने की कोशिश करने का फैसला किया, फिर उपयोगकर्ता द्वारा डिस्कनेक्ट होने के बाद कनेक्शन बंद कर दें।"
टोबलरप्वन

2

क्या आपके पास डंप करने के लिए कुछ स्रोत कोड हैं? यह डेटाबेस के लिए कनेक्शन बंद नहीं हो सकता है? HTTP कनेक्शन की प्रतीक्षा करने वाली प्रक्रियाएँ जो कभी बंद नहीं होती हैं।

क्या आप कुछ लॉग पोस्ट कर सकते हैं?

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

यह कोड में कहीं एक अनन्त लूप हो सकता है या एक db कनेक्शन को ऑन करने वाली क्रैश प्रक्रिया हो सकती है।

एनपीएम मॉड्यूल क्या उपयोग कर रहे हैं? क्या वे सभी नवीनतम हैं?

क्या आप अपवादों को पकड़ रहे हैं? देखें: http://geoff.greer.fm/2012/06/10/nodejs-dealing-with-errors/ देखें: /programming/10122245/capture-node-js-crash-reason

सामान्य सुझाव:

http://clock.co.uk/tech-blogs/preventing-http-raise-hangup-error-on-destroyed-socket-write-from-crashing-your-nodejs-server

http://blog.nodejitsu.com/keep-a-nodejs-server-up-with-forever

http://hectorcorrea.com/blog/running-a-node-js-web-site-in-production-a-beginners-guide

/programming/1911015/how-to-debug-node-js-applications

https://github.com/dannycoates/node-inspector

http://elegantcode.com/2011/01/14/taking-baby-steps-with-node-js-debugging-with-node-inspector/


1

प्रति उत्तर नहीं, क्योंकि आपका प्रश्न एक उत्तर-बिंदु वाले प्रश्न की तुलना में एक कहानी से अधिक है।

सिर्फ यह बताने के लिए कि मैंने सफलतापूर्वक सॉकेट के साथ एक नोड.जेएस सर्वर बनाया है। 700 बाइट्स के संदेश पेलोड औसत के साथ 1 मिलियन से अधिक लगातार कनेक्शन संभाल रहा है।

1Gbps पर नेटवर्क इंटरफेस कार्ड शुरुआत में संतृप्त था, और मैं सभी ग्राहकों को प्रकाशित घटनाओं से I / O प्रतीक्षा का बहुत कुछ देख रहा था।

प्रॉक्सी भूमिका से nginx को हटाने से भी कीमती मेमोरी वापस आ गई थी, क्योंकि केवल एक सर्वर के साथ एक मिलियन लगातार कनेक्शन तक पहुंचने के लिए, ओएस कॉन्फ़िगरेशन, एप्लिकेशन और ट्यूनिंग ओएस मापदंडों को जोड़ना एक कठिन काम है। ध्यान रखें कि यह केवल RAM के साथ बहुत कुछ करने योग्य है (लगभग 1M websockets कनेक्शन 16GB RAM खाता है, नोड के साथ। js, मुझे लगता है कि sock.js का उपयोग कम मेमोरी खपत के लिए आदर्श होगा, लेकिन अब के लिए, socket.io इतना खा लेता है)।

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

HTH,

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