हम डिप्लॉय को शून्य 502 एरर तक कैसे लाए
Mythex के बैकएंड को डिप्लॉय करने पर हर बार कुछ अनुरोध 502 Bad Gateway से विफल होते थे। ज़्यादा नहीं, पर डिप्लॉय के दौरान 502 का अर्थ है कि किसी का क्लिक कुछ नहीं कर पाया, या कोई बिल्ड जिसे वे देख रहे थे एक पल को रुक गया। हमने इसे दो अलग समस्याओं तक खोजा: एक स्व-उपचार वाला वॉचडॉग जो हमारे डिप्लॉय से लड़ रहा था, और उस अंतर के बीच जब कोई सर्वर सुनना बंद करता है और जब लोड बैलेंसर उसे ट्रैफ़िक भेजना बंद करता है। सुधार के बाद लगातार तीन प्रोडक्शन डिप्लॉय में गिनती 10 से 6 और फिर 0 हो गई।
सेटअप
हमारे API और ऑर्केस्ट्रेटर एक छोटे सर्वर समूह पर कंटेनर के रूप में चलते हैं, जो एक AWS Application Load Balancer (ALB) के पीछे है। डिप्लॉय एक बार में एक सर्वर अपडेट करता है: पुराने कंटेनर ड्रेन करता है, नए शुरू करता है, और आगे बढ़ता है। हर सर्वर पर एक वॉचडॉग जाँचता है कि कंटेनर चालू हैं और जो नहीं हैं उन्हें फिर शुरू करता है; यह इसलिए है कि रात 3 बजे क्रैश हुआ प्रोसेस बिना किसी के जागे लौट आए।
दोनों अपने आप में उचित हैं। साथ मिलकर वे सही नहीं थे।
समस्या 1: वॉचडॉग डिप्लॉय से दौड़ लगा रहा था
वॉचडॉग हर मिनट चलता था और एक विफल हेल्थ चेक पर "उपचार" करता था। डिप्लॉय जानबूझकर सेवाओं को 150 सेकंड तक ड्रेन करता है, जिस दौरान हेल्थ चेक का विफल होना अपेक्षित है। तो वॉचडॉग हर डिप्लॉय के दौरान सक्रिय हो जाता था।
ज़्यादातर वह दौड़ हानिरहित रूप से हार जाता था। एक बार वह जीत गया: उसने डिप्लॉय के बीच में कंपोज़ फ़ाइल (वह विवरण कि कौन से कंटेनर चलने चाहिए) फिर से लिख दी, और एक सर्वर पर कोई गेटवे कंटेनर नहीं छोड़ा, जबकि डिप्लॉय जॉब ने सफलता रिपोर्ट की।
सुधार:
- एक ही लॉक। डिप्लॉय अब सर्वर की बूटस्ट्रैप स्क्रिप्ट वाला ही फ़ाइल लॉक लेता है, ताकि वॉचडॉग और डिप्लॉय कभी एक साथ न चलें।
- चार बार, एक नहीं। वॉचडॉग तभी कार्रवाई करता है जब लगातार चार हेल्थ चेक विफल हों। ड्रेन हो रही सेवा अब मरी हुई नहीं दिखती।
- एक परिभाषा। कंपोज़ फ़ाइल का अब ठीक एक स्रोत है, जो सर्वरों पर प्रकाशित होता है, बजाय प्रतियों के जो अलग हो सकती थीं।
- भरोसा नहीं, जाँच। डिप्लॉय जॉब अब केवल इसलिए पास नहीं होता कि एक कमांड लौटी। वह सफल होने से पहले हर सर्वर पर API, ऑर्केस्ट्रेटर, गेटवे और पब्लिश वर्कर की जाँच करता है।
समस्या 2: सर्वर ट्रैफ़िक से पहले चला गया
दूसरी समस्या चुपचाप थी। जब डिप्लॉय एक सर्वर को ड्रेन करता है, तो सर्वर अपने हेल्थ एंडपॉइंट पर 503 देना शुरू करता है ताकि लोड बैलेंसर उसे रोटेशन से बाहर कर दे। हमारा सर्वर यह 5 सेकंड तक करता था, फिर बंद हो जाता था।
पर ALB हेल्थ केवल कभी-कभार जाँचता था, और किसी टार्गेट को रूट करना बंद करने से पहले लगातार कई विफल चेक चाहता था, कुल मिलाकर लगभग 60 सेकंड तक। तो लगभग 55 सेकंड तक लोड बैलेंसर उस सर्वर पर असली अनुरोध भेजता रहा जो सुनना बंद कर चुका था। वे हमारे 502 थे।
समाधान था दोनों समयरेखाओं को मिलाना:
- टार्गेट ग्रुप अब हर 5 सेकंड में जाँचता है और 2 विफलताओं के बाद टार्गेट को अस्वस्थ चिह्नित करता है, यानी अंत-से-अंत लगभग 10 सेकंड में पता चलता है।
- ड्रेन हेल्थ चेक विफल होने शुरू होने के बाद 15 सेकंड तक असली ट्रैफ़िक सर्व करता है, ताकि हमेशा ओवरलैप रहे।
- ये सेटिंग्स उस स्क्रिप्ट में हैं जो इन्फ़्रास्ट्रक्चर बनाती है, किसी कंसोल में नहीं जिसे किसी ने एक बार क्लिक किया हो।
संख्याओं को एक-दूसरे से मिलाए रखना
ऐसे टाइमआउट एक-दूसरे पर निर्भर होते हैं। ड्रेन को उस समय से लंबा होना चाहिए जितना बैलेंसर को विफलता पकड़ने में लगता है; ड्रेन और शटडाउन को कंटेनर के जबरन बंद होने से पहले पूरा होना चाहिए। छह महीने बाद कोई एक संख्या बदल दे और चुपचाप बग वापस ले आए, यह आसान है।
इसलिए हमने इन संबंधों को टेस्ट के रूप में लिखा: ड्रेन को हेल्थ-चेक अंतराल गुणा विफलता सीमा से लंबा होना चाहिए; दोबारा स्वस्थ होने में लगने वाला समय छोटा रहना चाहिए; पूरा ड्रेन कंटेनर की stop grace period के भीतर फ़िट होना चाहिए। एक संख्या बदलें और बाकी न बदलें, तो CI विफल होता है। हमने टेस्ट को भी म्यूटेशन-टेस्ट किया: हर संख्या को एक गलत मान पर बदला और जाँचा कि कोई टेस्ट उसे पकड़ता है।
डिप्लॉय मापना आसानी से गलत हो जाता है
हमारा पहला माप कहता था कि एक साफ़ डिप्लॉय लगभग 3% टूटा हुआ था। वह सही नहीं था। हम हर गैर-200 जवाब गिन रहे थे, और ड्रेन के दौरान हेल्थ एंडपॉइंट से आया 503 विफलता नहीं है; यह ड्रेन का अपना काम है, जो लोड बैलेंसर को बताता है कि उस सर्वर को न चुने जब तक वह असली अनुरोध सर्व करता है।
उपयोगकर्ता जो महसूस करते हैं वह 502 है: अनुरोध कुछ तक पहुँचा ही नहीं। केवल उन्हें गिनने पर असली तस्वीर मिली: तीन लगातार प्रोडक्शन डिप्लॉय में 10, फिर 6, फिर 0।
हमने क्या सीखा
- स्व-उपचार को नियोजित डाउनटाइम के बारे में पता होना चाहिए। जो वॉचडॉग डिप्लॉय और क्रैश में फ़र्क नहीं कर सकता, वह आख़िरकार डिप्लॉय से लड़ेगा।
- ड्रेन एक हैंडशेक है। सर्वर को तब तक सर्व करते रहना होगा जब तक लोड बैलेंसर साबित रूप से ट्रैफ़िक भेजना बंद न कर दे, और वह समय बैलेंसर पर सेट होता है, सर्वर पर नहीं।
- इनवेरियंट्स को टेस्ट के रूप में लिखें। ऑपरेशनल संख्याएँ बदलती हैं। जो टेस्ट उन्हें एक-दूसरे से जोड़ते हैं, वे नहीं बदलते।
- मापने से पहले तय करें कि आप क्या माप रहे हैं। "एरर" गलत मीट्रिक था; "वे अनुरोध जो कुछ तक नहीं पहुँचे" सही था।
अगर आप Mythex पर ऐप पब्लिश करते हैं, तो इनमें से कुछ भी आपको दिखाई नहीं देता, और यही उद्देश्य है। संबंधित: आपका पब्लिश किया ऐप रीपब्लिश के दौरान कैसे चालू रहता है।