आप त्रुटि की स्थिति को कैसे पुन: उत्पन्न करते हैं और देखते हैं कि आवेदन निष्पादित होने के समय क्या हो रहा है?
आप आवेदन के विभिन्न समवर्ती भागों के बीच बातचीत की कल्पना कैसे करते हैं?
मेरे अनुभव के आधार पर, इन दो पहलुओं का उत्तर इस प्रकार है:
ट्रेसिंग वितरित की गई
वितरित अनुरेखण वह तकनीक है जो आपके सिस्टम के प्रत्येक व्यक्तिगत समवर्ती घटक के लिए समय डेटा को कैप्चर करती है, और इसे आपको ग्राफिकल प्रारूप में प्रस्तुत करती है। समवर्ती निष्पादन के प्रतिनिधियों को हमेशा इंटरलेय किया जाता है, जिससे आप देख सकते हैं कि समानांतर में क्या चल रहा है और क्या नहीं है।
वितरित अनुरेखण वितरित (निश्चित रूप से) वितरित प्रणालियों में इसकी उत्पत्ति का कारण बनता है, जो कि परिभाषा अतुल्यकालिक और अत्यधिक समवर्ती हैं। वितरित अनुरेखण के साथ एक वितरित प्रणाली लोगों को सक्षम बनाती है:
क) महत्वपूर्ण अड़चनों की पहचान करें, ख) आपके आवेदन के आदर्श 'रन' का एक दृश्य प्रतिनिधित्व प्राप्त करता है, और ग) समवर्ती व्यवहार को निष्पादित करने में दृश्यता प्रदान करता है, घ) समय डेटा प्राप्त करता है जिसका उपयोग आपके परिवर्तनों के बीच अंतर का आकलन करने के लिए किया जा सकता है। प्रणाली (अत्यंत महत्वपूर्ण है अगर आपके पास मजबूत SLAs है)।
वितरित अनुरेखण के परिणाम हालांकि, हैं:
यह आपके सभी समवर्ती प्रक्रियाओं में ओवरहेड जोड़ता है, क्योंकि यह नेटवर्क पर संभावित रूप से निष्पादित करने और सबमिट करने के लिए अधिक कोड में अनुवाद करता है। कुछ मामलों में, यह ओवरहेड अत्यधिक महत्वपूर्ण है - यहां तक कि Google केवल सभी अनुरोधों के एक छोटे से सबसेट पर अपने ट्रेसिंग सिस्टम डैपर का उपयोग करता है ताकि उपयोगकर्ता अनुभव को बर्बाद न करें।
कई अलग-अलग उपकरण मौजूद हैं, जिनमें से सभी एक-दूसरे के साथ परस्पर जुड़े नहीं हैं। यह कुछ हद तक OpenTracing जैसे मानकों से समृद्ध है, लेकिन पूरी तरह से हल नहीं हुआ है।
यह आपको साझा संसाधनों और उनकी वर्तमान स्थिति के बारे में कुछ नहीं बताता है । आप अनुमान लगा सकते हैं कि एप्लिकेशन कोड और आपके द्वारा देखा जाने वाला ग्राफ़ आपको दिखा रहा है, लेकिन यह इस संबंध में एक उपयोगी उपकरण नहीं है।
वर्तमान उपकरण मान लेते हैं कि आपके पास मेमोरी और स्टोरेज है। एक समय सर्वर को होस्ट करना आपके अवरोधों के आधार पर सस्ता नहीं हो सकता है।
सॉफ्टवेयर को ट्रैक करने में त्रुटि
मैं मुख्य रूप से सेंट्री के ऊपर लिंक करता हूं क्योंकि यह सबसे व्यापक रूप से उपयोग किया जाने वाला टूल है, और अच्छे कारण के लिए - सेंट्री हाईजैक रनटाइम निष्पादन जैसे त्रुटि ट्रैकिंग सॉफ़्टवेयर एक साथ एक केंद्रीय सर्वर के सामने आने वाली त्रुटियों के ढेर का पता लगाने के लिए।
समवर्ती कोड में इस तरह के समर्पित सॉफ्टवेयर का शुद्ध लाभ:
- डुप्लिकेट त्रुटियां डुप्लिकेट नहीं हैं । दूसरे शब्दों में, यदि एक या अधिक समवर्ती सिस्टम एक ही अपवाद सामना करते हैं, संतरी जाएगा बढ़ाने के एक घटना की रिपोर्ट है, लेकिन घटना की दो प्रतियां प्रस्तुत नहीं।
इसका मतलब है कि आप यह पता लगा सकते हैं कि कौन सी समवर्ती प्रणाली अनुभव कर रही है कि किस प्रकार की त्रुटि के बिना अनगिनत युगपत त्रुटि रिपोर्टों के माध्यम से जाना जाता है। यदि आपको कभी भी वितरित सिस्टम से ईमेल स्पैम का सामना करना पड़ा है, तो आप जानते हैं कि नरक क्या महसूस करता है।
आप अपने समवर्ती प्रणाली के विभिन्न पहलुओं को 'टैग' भी कर सकते हैं (हालांकि यह मानता है कि आपके पास बिल्कुल एक धागे के ऊपर इंटरलेव्ड काम नहीं है, जो तकनीकी रूप से वैसे भी समवर्ती नहीं है क्योंकि थ्रेड बस कुशलता से कार्यों के बीच कूद रहा है, लेकिन फिर भी इवेंट हैंडलर को प्रोसेस करना होगा पूरा करना) और टैग द्वारा त्रुटियों का टूटना देखें।
- आप अपने रनटाइम अपवादों के साथ अतिरिक्त विवरण प्रदान करने के लिए इस त्रुटि से निपटने वाले सॉफ़्टवेयर को संशोधित कर सकते हैं। प्रक्रिया के क्या खुले संसाधन थे? क्या कोई साझा संसाधन है जो इस प्रक्रिया को पकड़े हुए था? किस उपयोगकर्ता को इस समस्या का अनुभव हुआ?
यह, सावधानीपूर्वक स्टैक निशान (और स्रोत नक्शे के अलावा, यदि आपको अपनी फ़ाइलों का एक छोटा संस्करण प्रदान करना है), यह निर्धारित करना आसान बनाता है कि समय का एक बड़ा हिस्सा क्या हो रहा है।
- (संतरी-विशिष्ट) आपके पास सिस्टम के टेस्ट रन के लिए एक अलग सेंट्री रिपोर्टिंग डैशबोर्ड हो सकता है, जिससे आप परीक्षण में त्रुटियों को पकड़ सकते हैं।
इस तरह के सॉफ्टवेयर के नुकसान में शामिल हैं:
सब कुछ की तरह, वे थोक जोड़ते हैं। उदाहरण के लिए, हो सकता है कि आप एम्बेडेड हार्डवेयर पर ऐसी प्रणाली न चाहें। मैं इस तरह के सॉफ्टवेयर के ट्रायल रन को करने की सलाह देता हूं, एक साधारण निष्पादन की तुलना करता है और इसके बिना एक बेकार मशीन पर कुछ सौ से अधिक रन करता है।
सभी भाषाएं समान रूप से समर्थित नहीं हैं, क्योंकि इनमें से कई प्रणालियां एक अपवाद को पकड़ने पर निर्भर हैं और सभी भाषाओं में मजबूत अपवाद नहीं हैं। कहा जा रहा है, सिस्टम के एक महान सौदे के लिए ग्राहक हैं।
उन्हें सुरक्षा जोखिम के रूप में उठाया जा सकता है, क्योंकि इनमें से कई प्रणालियां अनिवार्य रूप से बंद-स्रोत हैं। ऐसे मामलों में, उन पर शोध करने में अपना उचित परिश्रम करें, या यदि पसंद किया जाता है, तो अपना खुद का रोल करें।
वे हमेशा आपको आवश्यक जानकारी नहीं दे सकते हैं। यह दृश्यता को जोड़ने के सभी प्रयासों के साथ एक जोखिम है।
इनमें से अधिकांश सेवाओं को अत्यधिक समवर्ती वेब अनुप्रयोगों के लिए डिज़ाइन किया गया था, इसलिए प्रत्येक उपकरण आपके उपयोग के मामले के लिए एकदम सही नहीं हो सकता है।
संक्षेप में : दृश्यता किसी भी समवर्ती प्रणाली का सबसे महत्वपूर्ण हिस्सा है। किसी भी समय बिंदु पर सिस्टम की एक समग्र तस्वीर प्राप्त करने के लिए हार्डवेयर और डेटा के बारे में समर्पित डैशबोर्ड के साथ संयोजन में, ऊपर वर्णित दो तरीके, उस पहलू को संबोधित करने के लिए उद्योग भर में व्यापक रूप से उपयोग किए जाते हैं।
कुछ अतिरिक्त सुझाव
मैंने उन लोगों द्वारा कोड को ठीक करने की तुलना में अधिक समय बिताया है जो भयानक तरीकों से समवर्ती समस्याओं को हल करने की कोशिश करते हैं। हर बार, मुझे ऐसे मामले मिले हैं, जहां निम्नलिखित चीजें डेवलपर अनुभव को बेहतर कर सकती हैं (जो कि उपयोगकर्ता अनुभव के समान ही महत्वपूर्ण है):
प्रकारों पर भरोसा करना । टाइपिंग आपके कोड को मान्य करने के लिए मौजूद है, और एक अतिरिक्त गार्ड के रूप में रनटाइम पर उपयोग किया जा सकता है। जहां टाइपिंग मौजूद नहीं है, त्रुटियों को पकड़ने के लिए दावे और उपयुक्त त्रुटि हैंडलर पर भरोसा करें। समवर्ती कोड को रक्षात्मक कोड की आवश्यकता होती है , और प्रकार उपलब्ध सत्यापन का सबसे अच्छा प्रकार है।
- कोड घटकों के बीच परीक्षण लिंक , न केवल घटक ही। इसे एक पूर्ण विकसित एकीकरण परीक्षण के साथ भ्रमित न करें - जो हर घटक के बीच हर लिंक का परीक्षण करता है, और फिर भी यह केवल अंतिम स्थिति के वैश्विक सत्यापन के लिए दिखता है। यह त्रुटियों को पकड़ने का एक भयानक तरीका है।
एक अच्छा लिंक परीक्षण यह देखने के लिए जांचता है कि क्या, जब एक घटक अलगाव में किसी अन्य घटक से बात करता है , तो प्राप्त संदेश और भेजे गए संदेश वही आ जाते हैं जो आप की अपेक्षा करते हैं। यदि आपके पास दो या दो से अधिक घटक हैं जो साझा करने के लिए एक साझा सेवा पर निर्भर हैं, तो उन सभी को स्पिन करें, उन्हें केंद्रीय सेवा के माध्यम से संदेशों का आदान-प्रदान करें, और देखें कि क्या वे सभी मिल रहे हैं जो आप अंत में उम्मीद करते हैं।
घटकों के एक परीक्षण में बहुत सारे घटकों को शामिल करने वाले परीक्षणों को तोड़ना और प्रत्येक घटक के संचार के साथ-साथ आपको अपने कोड की वैधता पर विश्वास बढ़ाने का एक परीक्षण। इस तरह के कठोर शरीर होने से आप सेवाओं के बीच अनुबंधों को लागू करने के साथ-साथ अप्रत्याशित त्रुटियां भी पकड़ सकते हैं, जो एक बार में चल रही हैं।
- अपनी एप्लिकेशन स्थिति को मान्य करने के लिए सही एल्गोरिदम का उपयोग करें। मैं साधारण चीजों के बारे में बात कर रहा हूं, जैसे कि जब आपके पास एक मास्टर प्रक्रिया है, जो अपने सभी श्रमिकों को एक काम खत्म करने के लिए इंतजार कर रही है और केवल अगले चरण में जाना चाहते हैं यदि सभी कार्यकर्ता पूरी तरह से काम कर रहे हैं - यह वैश्विक का पता लगाने का एक उदाहरण है समाप्ति, जिसके लिए ज्ञात पद्धतियाँ जैसे कि सफरा का एल्गोरिथ्म मौजूद हैं।
इनमें से कुछ उपकरण भाषाओं के साथ आते हैं - उदाहरण के लिए, आपके कोड की गारंटी के लिए रस्ट का संकलन-समय पर कोई दौड़ की स्थिति नहीं होगी, जबकि गो में एक इनबिल्ट डेडलॉक डिटेक्टर है जो संकलन-समय पर भी चलता है। यदि आप उत्पादन हिट करने से पहले मुद्दों को पकड़ सकते हैं, तो यह हमेशा एक जीत है।
अंगूठे का एक सामान्य नियम: समवर्ती प्रणालियों में विफलता के लिए डिजाइन । यह अनुमान लगाएं कि आम सेवाएं दुर्घटनाग्रस्त होंगी या टूटेंगी। यह उन मशीनों के लिए भी वितरित किया जाता है जो मशीनों में वितरित नहीं होती हैं - एक मशीन पर समवर्ती कोड बाहरी निर्भरता (जैसे एक साझा लॉग फ़ाइल, एक रेडिस सर्वर, एक लानत MySQL सर्वर) पर भरोसा कर सकता है जो किसी भी समय गायब हो सकता है या हटाया जा सकता है। ।
ऐसा करने का सबसे अच्छा तरीका समय-समय पर एप्लिकेशन स्थिति को मान्य करना है - प्रत्येक सेवा के लिए स्वास्थ्य जांच करना, और सुनिश्चित करें कि उस सेवा के उपभोक्ताओं को खराब स्वास्थ्य की सूचना है। डॉकर जैसे आधुनिक कंटेनर उपकरण इसे काफी अच्छी तरह से करते हैं, और इसे सैंडबॉक्स चीजों का उपयोग करना चाहिए।
आप यह कैसे समझ सकते हैं कि समवर्ती क्या बनाया जा सकता है और क्या अनुक्रमिक बनाया जा सकता है?
मैंने एक उच्च समवर्ती प्रणाली पर काम करना सीखा सबसे बड़ा सबक यह है: आपके पास कभी पर्याप्त मैट्रिक्स नहीं हो सकते । मेट्रिक्स को आपके एप्लिकेशन में पूरी तरह से सब कुछ चलाना चाहिए - यदि आप सब कुछ नहीं माप रहे हैं तो आप इंजीनियर नहीं हैं।
मैट्रिक्स के बिना, आप कुछ बहुत महत्वपूर्ण काम नहीं कर सकते:
प्रणाली में परिवर्तन के द्वारा किए गए अंतर का आकलन करें। यदि आपको नहीं पता कि ट्यूनिंग नॉब ए बना हुआ मीट्रिक बी ऊपर जाता है और मीट्रिक सी नीचे जाता है, तो आप नहीं जानते कि आपके सिस्टम को कैसे ठीक किया जाए जब लोग आपके सिस्टम पर अप्रत्याशित रूप से घातक कोड को धक्का देते हैं (और वे आपके सिस्टम पर कोड को धक्का देंगे) ।
चीजों को बेहतर बनाने के लिए आपको आगे क्या करना है, इसे समझें। जब तक आप जानते हैं कि एप्लिकेशन मेमोरी पर कम चल रहे हैं, आप यह नहीं समझ सकते हैं कि आपको अधिक मेमोरी प्राप्त करनी चाहिए या अपने सर्वर के लिए अधिक डिस्क खरीदना चाहिए।
मेट्रिक्स इतने महत्वपूर्ण और आवश्यक हैं कि मैंने यह योजना बनाने के लिए एक सचेत प्रयास किया है कि मैं क्या मापना चाहता हूं इससे पहले कि मैं यह भी सोचूं कि एक सिस्टम की आवश्यकता क्या होगी। वास्तव में, मेट्रिक्स इतने महत्वपूर्ण हैं कि मेरा मानना है कि वे इस सवाल का सही जवाब हैं: आप केवल यह जानते हैं कि जब आप अपने कार्यक्रम में बिट्स क्या कर रहे हैं तो मापते हैं कि आपको अनुक्रमिक या समवर्ती क्या बनाया जा सकता है । उचित डिजाइन संख्याओं का उपयोग करता है, अनुमान नहीं।
कहा जा रहा है कि, निश्चित रूप से अंगूठे के कुछ नियम हैं:
अनुक्रमिक निर्भरता का तात्पर्य है। दो प्रक्रियाएँ अनुक्रमिक होनी चाहिए अगर एक कुछ फैशन में दूसरे पर निर्भर है। बिना निर्भरता वाली प्रक्रियाएं समवर्ती होनी चाहिए। हालाँकि, विफलता को स्ट्रीम को संभालने का एक तरीका है जो प्रक्रियाओं को अनिश्चित काल तक प्रतीक्षा करने से नहीं रोकता है।
एक ही कोर पर सीपीयू-बाउंड कार्य के साथ I / O बाध्य कार्य को कभी न मिलाएं। न करें (उदाहरण के लिए) एक वेब क्रॉलर लिखें जो एक ही धागे में दस समवर्ती अनुरोधों को लॉन्च करता है, जैसे ही वे आते हैं, उन्हें स्क्रैप करते हैं, और पांच सौ के पैमाने की उम्मीद करते हैं - I / O अनुरोध समानांतर में एक कतार में जाते हैं, लेकिन सीपीयू अभी भी क्रमिक रूप से उनके माध्यम से जाएगा। (यह सिंगल-थ्रेडेड इवेंट संचालित मॉडल एक लोकप्रिय है, लेकिन यह इस पहलू के कारण सीमित है - यह समझने के बजाय, लोग बस अपने हाथों को कुल्ला करते हैं और कहते हैं कि नोड आपको पैमाने नहीं देता है, आपको एक उदाहरण देने के लिए)।
एक एकल धागा बहुत सारे I / O काम कर सकता है। लेकिन अपने हार्डवेयर की संगति का पूरी तरह से उपयोग करने के लिए, सभी कोर पर कब्जा करने वाले थ्रेडपूल का उपयोग करें। ऊपर दिए गए उदाहरण में, केवल पाँच कार्य (छह-कोर मशीन पर एक कोर का उपयोग कर सकते हैं) को लॉन्च करने के लिए केवल CPU काम और I / O के लिए एक छठे पायथन धागे को लॉन्च करना आपके विचार से बहुत तेज़ होगा।
सीपीयू संगणना का लाभ उठाने का एकमात्र तरीका एक समर्पित थ्रेडपूल है। एक एकल धागा अक्सर I / O बाध्य कार्य के लिए पर्याप्त होता है। यही कारण है कि इवेंट-चालित वेब सर्वर जैसे कि नग्नेक्स स्केल बेहतर है (वे विशुद्ध रूप से I / O बाध्य कार्य करते हैं) Apache की तुलना में (जो सीपीयू की आवश्यकता वाले किसी चीज के साथ I / O बाध्य कार्य को स्वीकार करता है और अनुरोध के अनुसार एक प्रक्रिया शुरू करता है), लेकिन क्यों Node का उपयोग करने के लिए समानांतर में प्राप्त हज़ारों GPU गणना एक भयानक विचार है।