
यह श्रृंखला का अगला लेख है जिसमें बताया गया है कि हम सिटीमोबिल में हमारी सेवा उपलब्धता कैसे बढ़ा रहे हैं (आप पिछले भागों को
यहाँ और
यहाँ पढ़ सकते हैं)। आगे के भागों में, मैं दुर्घटनाओं और विस्तार के बारे में विस्तार से बात करूँगा। लेकिन पहले मुझे कुछ पर प्रकाश डालने दें, जिनके बारे में मुझे पहले लेख में बात करनी चाहिए थी लेकिन नहीं। मुझे अपने पाठकों की प्रतिक्रिया से पता चला। यह लेख मुझे इस कष्टप्रद कमी को ठीक करने का मौका देता है।
1. प्रस्तावना
एक पाठक ने मुझसे एक बहुत ही उचित सवाल पूछा: "राइड-हेलिंग सेवा के बैकएंड के बारे में क्या उलझन है?" यह एक अच्छा सवाल है। पिछली गर्मियों में, मैंने खुद से कहा कि सिटीमोबिल में काम करना शुरू करने से पहले बहुत ही सवाल। मैं सोच रहा था: "यह केवल एक टैक्सी सेवा है जिसके तीन-बटन ऐप हैं।" कितना मुश्किल हो सकता है? यह एक बहुत ही उच्च तकनीक वाला उत्पाद बन गया। थोड़ा स्पष्ट करने के लिए कि मैं किस बारे में बात कर रहा हूं और यह कितनी बड़ी तकनीकी बात है, मैं आपको सिटीबोबिल के कुछ उत्पाद निर्देशों के बारे में बताने जा रहा हूं:
- मूल्य निर्धारण। हमारी मूल्य निर्धारण टीम हर बिंदु पर और समय के प्रत्येक क्षण में सर्वश्रेष्ठ सवारी मूल्य की समस्या से निपटती है। मूल्य आंकड़ों और कुछ अन्य आंकड़ों के आधार पर आपूर्ति और मांग संतुलन भविष्यवाणी द्वारा निर्धारित किया जाता है। यह सब मशीन सीखने के आधार पर एक जटिल और लगातार विकासशील सेवा द्वारा किया जाता है। साथ ही मूल्य निर्धारण टीम विभिन्न भुगतान विधियों के कार्यान्वयन से संबंधित है, एक यात्रा को पूरा करने पर अतिरिक्त शुल्क, चार्जबैक, बिलिंग, भागीदारों और ड्राइवरों के साथ बातचीत।
- आदेश भेजना। कौन सी कार ग्राहक के आदेश को पूरा करती है? उदाहरण के लिए, कई यात्राओं को अधिकतम करने के संदर्भ में निकटतम वाहन चुनने का विकल्प सबसे अच्छा नहीं है। बेहतर विकल्प कारों और ग्राहकों से मेल खाना है ताकि इस विशिष्ट ग्राहक की संभावना को देखते हुए ट्रिप संख्या को अधिकतम करने के लिए इन विशिष्ट परिस्थितियों में अपने आदेश को रद्द कर दें (क्योंकि इंतजार बहुत लंबा है) और इस विशिष्ट ड्राइवर के आदेश को रद्द करने या तोड़फोड़ करने की संभावना है ( जैसे कि दूरी बहुत बड़ी है या कीमत बहुत छोटी है)।
- जियो। पते के बारे में सभी खोज और सुझाव, पिकअप पॉइंट, आगमन के अनुमानित समय का समायोजन (हमारे मैप सप्लाई पार्टनर हमें हमेशा ट्रैफ़िक के लिए भत्ते के साथ सटीक ईटीए जानकारी प्रदान नहीं करते हैं), प्रत्यक्ष और रिवर्स जियोकोडिंग सटीकता में वृद्धि, कार आगमन बिंदु सटीकता में वृद्धि। बहुत सारे डेटा, बहुत सारे एनालिटिक्स, बहुत सारे मशीन लर्निंग आधारित सेवाएं हैं।
- Antifraud। एक यात्री और एक चालक के लिए यात्रा लागत में अंतर (उदाहरण के लिए, छोटी यात्राओं में) घुसपैठियों के लिए एक आर्थिक प्रोत्साहन बनाता है जो हमारे पैसे चोरी करने की कोशिश कर रहा है। धोखाधड़ी से निपटना मेल स्पैम से निपटने के लिए कुछ हद तक समान है - सटीक और याद दोनों बहुत महत्वपूर्ण हैं। हमें अधिकतम संख्या में धोखाधड़ी (रिकॉल) को रोकने की आवश्यकता है, लेकिन साथ ही हम अच्छे उपयोगकर्ताओं को धोखाधड़ी (सटीक) के लिए नहीं ले सकते।
- चालक प्रोत्साहन टीम सब कुछ के विकास की देखरेख करती है जो विभिन्न प्रकार के प्रोत्साहनों के कारण ड्राइवरों और ड्राइवरों की वफादारी द्वारा हमारे मंच के उपयोग को बढ़ा सकती है। उदाहरण के लिए, एक्स यात्राएं पूरी करें और अतिरिक्त वाई पैसा प्राप्त करें। या जेड के लिए एक शिफ्ट खरीदें और बिना कमीशन के चारों ओर ड्राइव करें।
- ड्राइवर ऐप बैकएंड आदेशों की सूची, डिमांड मैप (यह एक ड्राइवर को दिखाता है कि उसे अपने मुनाफे को अधिकतम करने के लिए कहां जाना चाहिए), स्थिति में बदलाव, ड्राइवरों के साथ संचार की प्रणाली और बहुत सारे अन्य सामान।
- क्लाइंट ऐप बैकएंड (यह शायद सबसे स्पष्ट हिस्सा है और यही लोग आमतौर पर "टैक्सी बैकएंड" कहते हैं): ऑर्डर प्लेसमेंट, ऑर्डर की स्थिति की जानकारी, नक्शे पर छोटी कारों की आवाजाही, टिप्स बैकएंड आदि।
यह सिर्फ हिमशैल का सिरा है। बहुत अधिक कार्यक्षमता है। वहाँ एक बहुत ही सरल इंटरफ़ेस प्रतीत होता है के पीछे हिमशैल का एक विशाल पानी के नीचे का हिस्सा है।
और अब हम दुर्घटनाओं पर वापस जाते हैं। छह महीने के इतिहास में लॉगिंग के परिणामस्वरूप निम्नलिखित वर्गीकरण हुए:
- खराब रिलीज: 500 आंतरिक सर्वर त्रुटियां;
- खराब रिलीज: डेटाबेस अधिभार;
- दुर्भाग्यपूर्ण मैनुअल सिस्टम ऑपरेशन इंटरैक्शन;
- ईस्टर अंडे;
- बाहरी कारण;
- खराब रिलीज: टूटी हुई कार्यक्षमता।
नीचे हम उन निष्कर्षों के बारे में विस्तार से जानेगे जो हमने अपने सबसे आम दुर्घटना प्रकारों के बारे में बनाए हैं।
2. खराब रिलीज: 500 आंतरिक सर्वर त्रुटियां
हमारी बैकेंड ज्यादातर PHP में लिखी जाती है - एक कमजोर टाइप की गई व्याख्या वाली भाषा। हम एक कोड जारी करेंगे जो कक्षा या फ़ंक्शन नाम में त्रुटि के कारण क्रैश हो गया। और 500 त्रुटि होने पर यह केवल एक उदाहरण है। यह कोड में तार्किक त्रुटि के कारण भी हो सकता है; गलत शाखा जारी की गई थी; कोड वाला फ़ोल्डर गलती से हटा दिया गया था; परीक्षण के लिए आवश्यक अस्थायी कलाकृतियों को कोड में छोड़ दिया गया; तालिका संरचना को कोड के अनुसार परिवर्तित नहीं किया गया था; आवश्यक क्रोन स्क्रिप्ट पुनः आरंभ या बंद नहीं की गईं।
हम धीरे-धीरे इस मुद्दे को चरणों में संबोधित कर रहे थे। खराब रिलीज के कारण खोई गई यात्राएं स्पष्ट रूप से इसके उत्पादन के समय के अनुपात में हैं। इसलिए, हमें अपना सर्वश्रेष्ठ प्रदर्शन करना चाहिए और उत्पादन के समय में खराब रिलीज को कम करना सुनिश्चित करना चाहिए। विकास प्रक्रिया में कोई भी बदलाव जो खराब समय के परिचालन समय के औसत समय को 1 सेकंड तक कम कर देता है, व्यवसाय के लिए अच्छा है और इसे लागू किया जाना चाहिए।
खराब रिलीज और वास्तव में, उत्पादन में किसी भी दुर्घटना में दो राज्य हैं जिन्हें हमने "निष्क्रिय अवस्था" और "एक सक्रिय चरण" नाम दिया है। निष्क्रिय अवस्था के दौरान हमें अभी तक किसी दुर्घटना की जानकारी नहीं है। सक्रिय चरण का मतलब है कि हम पहले से ही जानते हैं। निष्क्रिय अवस्था में एक दुर्घटना शुरू होती है; समय में यह सक्रिय अवस्था में चला जाता है - कि जब हम इसके बारे में पता लगाते हैं और इसे संबोधित करना शुरू करते हैं: पहले हम इसका निदान करते हैं और फिर इसे ठीक करते हैं।
किसी भी आउटेज की अवधि को कम करने के लिए, हमें सक्रिय और निष्क्रिय चरणों की अवधि को कम करने की आवश्यकता है। एक खराब रिलीज के लिए जाता है क्योंकि यह एक तरह का आउटेज माना जाता है।
हमने आउटेज की समस्या निवारण के इतिहास का विश्लेषण करना शुरू किया। खराब रिलीज़ जो हमने अनुभव की जब हमने बस दुर्घटनाओं का विश्लेषण करना शुरू किया, तो औसतन 20-25 मिनट की गिरावट (पूर्ण या आंशिक) हुई। निष्क्रिय चरण में आमतौर पर 15 मिनट लगते हैं, और सक्रिय एक - 10 मिनट। निष्क्रिय अवस्था के दौरान हमें उपयोगकर्ता शिकायतें मिलेंगी जिन्हें हमारे कॉल सेंटर द्वारा संसाधित किया गया था; और कुछ विशिष्ट सीमा के बाद कॉल सेंटर एक सुस्त चैट में शिकायत करेगा। कभी-कभी हमारे एक सहकर्मी को टैक्सी न मिलने की शिकायत होती। सहकर्मी की शिकायत एक गंभीर समस्या के बारे में संकेत देती है। एक ख़राब रिलीज़ के सक्रिय चरण में प्रवेश करने के बाद, हमने दुर्घटना के कारणों का पता लगाने के लिए हालिया रिलीज़, विभिन्न ग्राफ़ और लॉग का विश्लेषण करते हुए समस्या निदान शुरू किया। कारणों का निर्धारण करने पर, हम वापस रोल करेंगे यदि खराब रिलीज नवीनतम थी या हम फिर से प्रतिबद्ध के साथ एक नई तैनाती करेंगे।
यह खराब रिलीज़ हैंडलिंग प्रक्रिया है जिसे हम सुधारने के लिए निर्धारित किया गया था।
निष्क्रिय चरण: 20 मिनट।
सक्रिय चरण: 10 मिनट।
3. निष्क्रिय अवस्था में कमी
सबसे पहले, हमने देखा कि अगर एक खराब रिलीज 500 त्रुटियों के साथ थी, तो हम बता सकते हैं कि उपयोगकर्ताओं की शिकायत के बिना भी एक समस्या हुई थी। सौभाग्य से, सभी 500 त्रुटियों को नए रेलिक में लॉग इन किया गया था (यह हमारे द्वारा उपयोग की जाने वाली निगरानी प्रणाली में से एक है) और हमें जो करना था, वह सभी 500 त्रुटियों की एक विशिष्ट संख्या से अधिक के बारे में एसएमएस और आईवीआर सूचनाएं जोड़ना था। समय बीतने के साथ-साथ दहलीज को लगातार नीचे किया जाएगा।
एक दुर्घटना के समय की प्रक्रिया इस तरह दिखाई देगी:
- एक इंजीनियर एक रिलीज को तैनात करता है।
- रिलीज एक दुर्घटना (500 के बड़े पैमाने पर राशि) की ओर जाता है।
- पाठ संदेश प्राप्त होता है।
- इंजीनियर और डेपॉप्स इसे देखने लगते हैं। कभी-कभी तुरंत नहीं, लेकिन 2-3 मिनट में: पाठ संदेश में देरी हो सकती है, फोन की आवाज़ बंद हो सकती है; और निश्चित रूप से, इस पाठ को प्राप्त करने पर तत्काल प्रतिक्रिया की आदत रातोंरात नहीं बन सकती है।
- दुर्घटना सक्रिय चरण शुरू होता है और पहले की तरह ही 10 मिनट तक रहता है।
नतीजतन, "खराब रिलीज: 500 आंतरिक सर्वर त्रुटियां" प्रकार का सक्रिय चरण एक रिलीज के 3 मिनट बाद शुरू होगा। इसलिए, निष्क्रिय चरण को 15 मिनट से घटाकर 3 कर दिया गया था।
परिणाम:
निष्क्रिय चरण: 3 मिनट।
सक्रिय चरण: 10 मिनट।
4. एक निष्क्रिय चरण की और कमी
भले ही निष्क्रिय चरण 3 मिनट तक कम हो गया था, यह अभी भी हमें सक्रिय से अधिक परेशान करता है क्योंकि सक्रिय चरण के दौरान हम समस्या को ठीक करने की कोशिश कर रहे थे, और निष्क्रिय अवस्था के दौरान सेवा पूरी तरह से या आंशिक रूप से नीचे थी, और हम बिल्कुल अनाड़ी थे।
निष्क्रिय अवस्था को और कम करने के लिए, हमने प्रत्येक रिलीज के बाद अपने इंजीनियरों के समय के 3 मिनट का बलिदान करने का फैसला किया। यह विचार बहुत सरल था: हम कोड को तैनात करेंगे और तीन मिनट बाद तक हम न्यू रिले, सेंट्री और किबाना में 500 त्रुटियों की तलाश कर रहे थे। जैसे ही हमने एक मुद्दा देखा, हम इसे संबंधित कोड मान लेंगे और समस्या निवारण शुरू कर देंगे।
हमने आंकड़ों के आधार पर इस तीन मिनट की अवधि को चुना: कभी-कभी 1-2 मिनट के भीतर ग्राफ़ में मुद्दे दिखाई देते थे, लेकिन बाद में 3 मिनट में कभी नहीं।
इस नियम को डू और नॉट में जोड़ा गया था। सबसे पहले, इसका हमेशा पालन नहीं किया गया था, लेकिन समय के साथ हमारे इंजीनियरों को इस नियम की आदत हो गई जैसे कि उन्होंने बुनियादी स्वच्छता के लिए किया था: सुबह के दांतों को ब्रश करना कुछ समय भी लेता है, लेकिन यह अभी भी आवश्यक है।
नतीजतन, निष्क्रिय चरण 1 मिनट तक कम हो गया था (रेखांकन अभी भी कभी-कभी देर हो रहे थे)। इसने एक अच्छा बोनस के रूप में सक्रिय चरण को भी कम कर दिया। क्योंकि अब एक इंजीनियर तैयार समस्या का सामना करेगा और तुरंत अपने कोड को वापस करने के लिए तैयार होगा। हालांकि यह हमेशा मदद नहीं करता था, क्योंकि समस्या किसी अन्य व्यक्ति द्वारा एक साथ तैनात रिलीज के कारण हो सकती थी। उस ने कहा, औसतन सक्रिय चरण पांच मिनट तक कम हो गया।
परिणाम:
निष्क्रिय चरण: 1 मिनट।
सक्रिय चरण: 5 मिनट।
5. एक सक्रिय चरण की और कमी
हम 1-मिनट के निष्क्रिय चरण से अधिक या कम संतुष्ट हो गए और एक सक्रिय चरण को और कम करने के बारे में सोचने लगे। सबसे पहले हमने आउटेज के इतिहास पर अपना ध्यान केंद्रित किया (यह हमारे नंबर की इमारत में एक आधारशिला होता है!) और पता चला कि ज्यादातर मामलों में हम तुरंत एक रिलीज वापस नहीं करते हैं क्योंकि हम जानते नहीं हैं। हमें किस संस्करण के लिए जाना चाहिए: कई समानांतर रिलीज़ हैं। इस समस्या को हल करने के लिए हमने निम्नलिखित नियम की शुरुआत की (और इसे डूज़ एंड डोंट में लिखा है): रिलीज से ठीक पहले किसी को एक सुस्त चैट में सभी को सूचित करना चाहिए कि आप क्या करने वाले हैं और क्यों? दुर्घटना के मामले में किसी को लिखना चाहिए: "दुर्घटना, तैनात न करें!" हमने उन लोगों को भी सूचित करना शुरू कर दिया जो एसएमएस के माध्यम से रिलीज के बारे में चैट नहीं पढ़ते हैं।
यह सरल नियम एक जारी दुर्घटना के दौरान काफी कम संख्या में रिलीज़ हुआ, समस्या निवारण की अवधि कम हो गई, और सक्रिय चरण को 5 मिनट से घटाकर 3 कर दिया।
परिणाम:
निष्क्रिय चरण: 1 मिनट।
सक्रिय चरण: 3 मिनट।
6. एक सक्रिय चरण की भी बड़ी कमी
इस तथ्य के बावजूद कि हमने सभी रिलीज़ और दुर्घटनाओं के संबंध में चैट में चेतावनी पोस्ट की है, दौड़ की स्थिति अभी भी कभी-कभी होती है - किसी ने रिलीज के बारे में पोस्ट किया और उसी क्षण एक अन्य इंजीनियर तैनात था; या कोई दुर्घटना हुई, हमने चैट में इसके बारे में लिखा था, लेकिन किसी ने उसका कोड तैनात कर दिया था। इस तरह की परिस्थितियाँ लंबे समय तक समस्या निवारण करती हैं। इस मुद्दे को हल करने के लिए, हमने समानांतर रिलीज पर स्वत: प्रतिबंध लागू किया। यह एक बहुत ही सरल विचार था: प्रत्येक रिलीज़ के 5 मिनट बाद, CI / CD सिस्टम किसी और के लिए एक और परिनियोजन को रोक देता है लेकिन नवीनतम रिलीज़ लेखक (ताकि वह ज़रूरत पड़ने पर हॉटफ़िक्स को वापस ला सके या तैनात कर सके) और कई अनुभवी डेवलपर्स (में आपातकाल का मामला)। इससे अधिक, सीआई / सीडी प्रणाली दुर्घटनाओं के समय में तैनाती को रोकती है (अर्थात, दुर्घटना शुरू होने की सूचना आने के बाद से और इसके समाप्त होने के बारे में अधिसूचना आने तक)।
इसलिए, हमारी प्रक्रिया इस तरह दिखना शुरू हुई: एक अभियंता एक विज्ञप्ति जारी करता है, तीन मिनट के लिए ग्राफ़ पर नज़र रखता है, और उसके बाद कोई भी एक और दो मिनट के लिए कुछ भी तैनात नहीं कर सकता है। यदि कोई समस्या होती है, तो इंजीनियर रिलीज़ को वापस रोल करता है। इस नियम ने काफी समस्या निवारण को सरल बनाया, और सक्रिय और निष्क्रिय चरणों की कुल अवधि 3 + 1 = 4 मिनट से घटाकर 1 + 1 = 2 मिनट कर दी।
लेकिन दो मिनट की दुर्घटना भी बहुत हुई। इसलिए हम अपनी प्रक्रिया अनुकूलन पर काम करते रहे।
परिणाम:
निष्क्रिय चरण: 1 मिनट।
सक्रिय चरण: 1 मिनट।
7. स्वचालित दुर्घटना निर्धारण और रोलबैक
हम कुछ समय के लिए सोच रहे थे कि खराब रिलीज के कारण होने वाली दुर्घटनाओं की अवधि को कैसे कम किया जाए। यहां तक कि हमने खुद को
tail -f error_log | grep 500
में देखने के लिए मजबूर करने की कोशिश की
tail -f error_log | grep 500
tail -f error_log | grep 500
। लेकिन अंत में, हमने कठोर स्वचालित समाधान का विकल्प चुना।
संक्षेप में, यह एक स्वचालित रोलबैक है। हमें एक अलग वेब सर्वर मिल गया है और इसे हमारे वेब सर्वर के बाकी हिस्सों की तुलना में 10 गुना कम बैलेंसर के माध्यम से लोड किया गया है। प्रत्येक रिलीज़ को इस अलग सर्वर पर CI / CD सिस्टम द्वारा स्वचालित रूप से तैनात किया जाएगा (हमने इसे
प्रीप्रोड कहा है
, लेकिन इसके नाम के बावजूद यह वास्तविक उपयोगकर्ताओं से वास्तविक भार प्राप्त करेगा)। फिर स्क्रिप्ट
tail -f error_log | grep 500
tail -f error_log | grep 500
। यदि एक मिनट के भीतर कोई 500 त्रुटि नहीं हुई, तो CI / CD अन्य वेब सर्वर पर उत्पादन में नई रिलीज को तैनात करेगा। मामले में त्रुटियां होने पर, सिस्टम ने इसे वापस ला दिया। बैलेंसर स्तर पर, सभी अनुरोधों के परिणामस्वरूप प्रीप्रोड पर 500 त्रुटियां फिर से एक उत्पादन वेब सर्वर पर भेजी जाएंगी।
इस उपाय ने 500 त्रुटियों को शून्य पर प्रभाव को कम कर दिया। कहा कि, स्वचालित नियंत्रण में बग के मामले में, हमने अपने तीन मिनट के ग्राफ़ घड़ी नियम को समाप्त नहीं किया। यह सब खराब रिलीज और 500 त्रुटियों के बारे में है। आइए अगले प्रकार की दुर्घटनाओं पर चलते हैं।
परिणाम:
निष्क्रिय चरण: 0 मिनट।
सक्रिय चरण: 0 मिनट।
आगे के भागों में, मैं सिटीमोबिल अनुभव में अन्य प्रकार के आउटेज के बारे में बात करने जा रहा हूं और हर आउटेज प्रकार के बारे में विस्तार से जाना; मैं आपको उन निष्कर्षों के बारे में भी बताऊंगा जो हमने आउटेज के बारे में किए थे, हमने विकास प्रक्रिया को कैसे संशोधित किया, हमने किस स्वचालन को पेश किया। देखते रहो!