हर इंजीनियरिंग टीम एक ऐसा सिस्टम चाहती है जो बिना किसी परेशानी के बढ़ता रहे। हम कल्पना करते हैं कि ट्रैफिक सुचारू रूप से बढ़ रहा है, सर्वर सही ढंग से चल रहे हैं, और राजस्व (revenue) लगातार ऊपर जा रहा है। फिर वास्तविकता सामने आती है। एक वायरल मार्केटिंग कैंपेन उपयोगकर्ताओं की लहर भेज देता है, डेटाबेस लॉक हो जाता है, और कोई रात के तीन बजे घबराहट में सेवाओं (services) को रीस्टार्ट कर रहा होता है। हमारी स्वाभाविक प्रतिक्रिया टूल्स को दोष देना होती है। हम खुद से कहते हैं कि हमें अधिक कोर्स (cores), तेज़ डिस्क, या एक और कैशिंग लेयर की ज़रूरत थी। लेकिन विकास हार्डवेयर से नहीं आता। यह संरचना (structure) से आता है। यदि आपका आधार भार को वितरित नहीं कर सकता, तो हर नया उपयोगकर्ता जीत के बजाय एक बोझ बन जाता है।

टूटे हुए आधार को टूल्स नहीं बचा सकते

आप सौ क्लाउड इंस्टेंस (cloud instances) शुरू कर सकते हैं, विभिन्न भौगोलिक क्षेत्रों के बीच लोड बैलेंसर जोड़ सकते हैं, और एक ग्लोबल कंटेंट डिलीवरी नेटवर्क में हर स्टैटिक एसेट को कैश कर सकते हैं। ये 'फोर्स मल्टीप्लायर' (force multipliers) हैं। फिर भी, शून्य को गुणा करने पर भी शून्य ही मिलता है। उलझी हुई डिपेंडेंसीज़ वाला एक मोनोलिथिक एप्लिकेशन (monolithic application) अपने ही भार से दब जाएगा, चाहे उसके नीचे कितना भी शक्तिशाली हार्डवेयर क्यों न हो।

एक ऐसे ऑनलाइन स्टोर की कल्पना करें जहाँ प्रोडक्ट कैटलॉग, पेमेंट प्रोसेसिंग और यूजर ऑथेंटिकेशन, सब एक ही कोडबेस में हों। जब चेकआउट फ्लो धीमा होता है, तो पूरी साइट रेंगने लगती है। लॉगिन पेज अटकने लगता है। ब्राउज़िंग अनुभव प्रभावित होता है। आप बाकी सब कुछ स्केल किए बिना केवल बॉटलनेक (bottleneck) को स्केल नहीं कर सकते। यह महंगा, अक्षम और नाजुक है। आप अंततः उस कंप्यूट पावर के लिए भुगतान करते हैं जिसका किसी को लाभ नहीं होता, जबकि आपके उपयोगकर्ता उन पेजों का इंतज़ार करते रहते हैं जिन्हें तुरंत लोड हो जाना चाहिए था।

आर्किटेक्चर ही इस जाल का समाधान है। यह वह अदृश्य कंकाल है जो यह तय करता है कि आपके टूल्स आपकी मदद करेंगे या नुकसान।

एक ठोस आर्किटेक्चर का वास्तव में क्या अर्थ है

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

एक अच्छा आर्किटेक्चर आपको निर्णय बदलने की गुंजाइश देता है। यह स्पष्ट सीमाएँ निर्धारित करता है ताकि एक टीम का प्रयोग दूसरी टीम के प्रोडक्शन वर्कलोड को अस्थिर न कर दे। यह विफलता (failure) को एक आश्चर्य के बजाय एक सामान्य परिचालन स्थिति के रूप में देखता है। जब आप विफलता को ध्यान में रखकर डिज़ाइन करते हैं, तो आप कांच के घर बनाना बंद कर देते हैं और ऐसी संरचनाएं बनाना शुरू करते हैं जो लचीली होती हैं।

एक व्यावहारिक पैटर्न के रूप में माइक्रोसर्विसेज

उस तरह की संरचना प्राप्त करने का एक व्यावहारिक तरीका अपने एप्लिकेशन को माइक्रोसर्विसेज (microservices) में विभाजित करना है। एक विशाल कोडबेस के बजाय, आप ऐप को छोटे हिस्सों में बाँट देते हैं। प्रत्येक हिस्सा एक विशिष्ट कार्य संभालता है। पेमेंट सर्विस ट्रांजेक्शन प्रोसेस करती है। इन्वेंट्री सर्विस स्टॉक को ट्रैक करती है। नोटिफिकेशन सर्विस ईमेल और टेक्स्ट मैसेज भेजती है। वे डायरेक्ट मेमोरी एक्सेस या साझा डेटाबेस टेबल के बजाय परिभाषित इंटरफेस के माध्यम से संवाद करते हैं।

यह अलगाव तकनीकी और संगठनात्मक दोनों रूप से काम करने की वास्तविक गुंजाइश पैदा करता है।

पूरे सिस्टम को तोड़े बिना छोटे हिस्सों को अपडेट करें

जब सेवाएँ छोटी और केंद्रित होती हैं, तो आप कैस्केड विफलता (cascade failure) के जोखिम के बिना एक हिस्से को पैच कर सकते हैं। यदि आपकी टीम को शिपिंग कैलकुलेशन एल्गोरिदम में कोई बग मिलता है, तो आप उस सर्विस को ठीक करते हैं और उसे स्वतंत्र रूप से तैनात (deploy) करते हैं। बाकी एप्लिकेशन चलता रहता है। उपयोगकर्ता अभी भी उत्पादों को ब्राउज़ करते हैं, लॉगिन करते हैं, और अपने कार्ट में आइटम जोड़ते हैं। किसी भी एकल परिवर्तन का 'ब्लास्ट रेडियस' (blast radius) बहुत छोटा रहता है। इसकी तुलना एक मोनोलिथ से करें जहाँ एक हेल्पर फंक्शन में टाइपो (typo) होने से चेकआउट, रजिस्ट्रेशन और रिपोर्टिंग सब एक साथ टूट सकते हैं।

ट्रैफिक बढ़ने पर विशिष्ट कार्यों को स्केल करें

एप्लिकेशन में ट्रैफिक कभी भी एक समान नहीं होता है। एक फ्लैश सेल के दौरान, आपकी ऑर्डर पाइपलाइन पर दबाव हो सकता है जबकि आपका कंटेंट मैनेजमेंट सिस्टम लगभग खाली बैठा हो। एक टाइटली कपल्ड सिस्टम (tightly coupled system) में, आप या तो सब कुछ स्केल करते हैं या कुछ भी नहीं। माइक्रोसर्विसेज के साथ, आप अपने संसाधनों को सटीक रूप से लक्षित करते हैं। चेकआउट सर्विस के अधिक इंस्टेंस शुरू करें। प्रोडक्ट कैटलॉग को उसके सामान्य स्तर पर चलने दें। किसी प्रोडक्ट लॉन्च के दौरान, आपके इमेज प्रोसेसिंग वर्कर्स हजारों थंबनेल की कतार बना सकते हैं जबकि आपका सर्च इंडेक्स शांत रह सकता है। केवल इमेज वर्कर्स की ज़रूरत को पूरा करने के लिए सर्च क्लस्टर का विस्तार करने का कोई कारण नहीं है। आप वहीं पैसा खर्च करते हैं जहाँ उपयोगकर्ताओं को उसका अनुभव होता है, और आपका सिस्टम दबाव में भी रिस्पॉन्सिव बना रहता है।

लंबे डाउनटाइम के बिना नया कोड तैनात करें

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

नए फीचर्स तेज़ी से बनाएं

बड़े कोडबेस सावधानी पैदा करते हैं। एक एकल बदलाव के लिए हजारों लाइनों के असंबंधित लॉजिक को समझने, घंटों तक चलने वाले रिग्रेशन टेस्ट और ऐसे डिप्लॉयमेंट शेड्यूल की आवश्यकता होती है जो रॉकेट लॉन्च की तरह महसूस होते हैं। छोटी सेवाएं उस डर को खत्म कर देती हैं। एक टीम उस सर्विस में कुछ सौ लाइनें बदलकर एक नया फीचर बना सकती है जिसे वे गहराई से जानते हैं। वे उसी दिन कमिट, टेस्ट और शिप कर सकते हैं। वह रफ़्तार बढ़ती जाती है। जब सेवाएं स्पष्ट ज़िम्मेदारियों द्वारा परिभाषित होती हैं, तो टीमें एक-दूसरे के काम में दखल देना बंद कर देती हैं। वे अपने डोमेन के अंत तक (end to end) के मालिक होते हैं।

स्वतंत्रता बड़े व्यवधानों को रोकती है

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

एक चेतावनी: बिना सोचे-समझे विभाजित न करें

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

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

इरादे के साथ शुरुआत करें

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

असली निष्कर्ष

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