प्रतिनिधि इंटरव्यू विषय

सिस्टम डिज़ाइन इंटरव्यू: एक रेज़िलिएंट बूटस्ट्रैप API डिज़ाइन करें

सिस्टम डिज़ाइनकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

एक क्लाइंट को अपनी पहली स्क्रीन रेंडर करने से पहले प्रोफ़ाइल, अनुमतियों (permissions), और एक पर्सनलाइज़्ड फ़ीड की आवश्यकता होती है। 300 ms के p95 बजट के साथ 2,000 अनुरोध प्रति सेकंड पर एक बूटस्ट्रैप API डिज़ाइन करें, जिसमें आंशिक प्रतिक्रियाएं (partial responses), डिपेंडेंसी विफलताएं, पुनः प्रयास (retries) और ऑब्ज़र्वेबिलिटी शामिल हों।

प्रॉम्प्ट और दायरा

बूटस्ट्रैप एंडपॉइंट तीन डाउनस्ट्रीम कॉलों को ऑर्केस्ट्रेट करता है। एक सही शैल (shell) के लिए प्रोफ़ाइल और अनुमतियां आवश्यक हैं; फ़ीड बासी (stale) या अनुपस्थित हो सकती है। एंडपॉइंट को एक टाइप्ड रिस्पॉन्स लौटाना चाहिए जो क्लाइंट को सुरक्षित अनुभागों को स्वतंत्र रूप से रेंडर करने की अनुमति देता है। 300 ms के p95 बजट में ऑर्केस्ट्रेशन ओवरहेड शामिल है, और डिज़ाइन में यह स्पष्ट होना चाहिए कि कौन सा डेटा और कितने समय के लिए कैश किया जा सकता है।

इंटरव्यूअर क्या जांच रहा है

  • उपयोगकर्ता-दृश्य आवश्यकताओं से पैरेललिज्म, टाइमआउट बजट और विफलता सिमेंटिक्स प्राप्त करना।
  • अनुपलब्ध डेटा, रिक्त परिणाम और डिपेंडेंसी त्रुटि के बीच अंतर करना।
  • लोड को कई गुना बढ़ाए बिना पुनः प्रयासों (retries), सर्किट ब्रेकर्स, बल्कहेड्स और कैश नीति को संयोजित करना।
  • एक विकसित होने योग्य (evolvable) रिस्पॉन्स कॉन्ट्रैक्ट और उपयोगी ऑपरेशनल सिग्नल डिज़ाइन करना।

पूछे जाने वाले स्पष्टीकरण प्रश्न

पूछें कि क्या अनुमतियाँ बासी (stale) हो सकती हैं, क्या फ़ीड डेटा की कोई ताजगी सीमा (freshness limit) है, क्या क्लाइंट प्रोग्रेसिव रूप से रेंडर कर सकता है, और क्या कॉल एक ही टेनेंट या प्राधिकरण संदर्भ (authorization context) साझा करते हैं। यदि अनुमतियों को कभी भी बासी होने की अनुमति नहीं है, तो वे क्रिटिकल पाथ पर रहते हैं; यदि फ़ीड का पांच मिनट का फ्रेशनेस लक्ष्य है, तो stale-while-revalidate कैश लेटेंसी को सुरक्षित रख सकता है।

30-सेकंड का उत्तर

मैं गेटवे को एक बार प्रमाणित करने, प्रोफ़ाइल, अनुमतियों और फ़ीड कॉलों को समानांतर में फैन आउट करने और असेंबली के लिए एक समय सीमा (deadline) आरक्षित करने के लिए डिज़ाइन करूँगा। आवश्यक अनुभाग फेल-क्लोज़्ड (fail closed) होते हैं; वैकल्पिक अनुभाग कारण कोड और फ्रेशनेस टाइमस्टैम्प के साथ एक स्पष्ट अनुपलब्ध स्थिति लौटाते हैं। पुनः प्रयास केवल क्षणिक (transient), आइडम्पोटेंट कॉलों तक सीमित होते हैं और एक साझा बजट का उपभोग करते हैं। प्रति-डिपेंडेंसी टाइमआउट, बल्कहेड्स, सर्किट ब्रेकर्स, पुराना कैश और एक टाइप्ड problem-details एन्वेलप किसी एक आउटेज को शैल को ब्लैंक करने से रोकते हैं। मेट्रिक्स अनुभाग-स्तरीय सफलता, समय सीमा समाप्ति, बासी सर्विंग और डिपेंडेंसी संतृप्ति को ट्रैक करते हैं।

चरण-दर-चरण गहन विश्लेषण

1. समय और समवर्ती (concurrency) बजट निर्धारित करें

2,000 अनुरोध प्रति सेकंड पर, तीन क्रमिक कॉलें 300 ms के बजट को बर्बाद करती हैं। समवर्ती रूप से फैन आउट करें, प्रत्येक डिपेंडेंसी को समग्र समय सीमा से कम की एक समय सीमा दें, और असेंबली तथा सीरियलाइज़ेशन को शेष समय के भीतर रखें। सीमित (bounded) कनेक्शन पूल और प्रति-अनुरोध रद्दीकरण सिग्नल का उपयोग करें ताकि समय समाप्त हो जाने पर डिपेंडेंसी कार्य का उपभोग करना बंद कर दे।

2. आंशिक-प्रतिक्रिया सिमेंटिक्स परिभाषित करें

प्रत्येक अनुभाग के लिए स्थिति के साथ एक स्थिर एन्वेलप लौटाएं: ready, stale, या unavailable। एक मशीन-पठनीय कारण और डेटा टाइमस्टैम्प शामिल करें, लेकिन आंतरिक होस्टनामों को लीक न करें। प्रोफ़ाइल या अनुमतियों की त्रुटियों को फेल-क्लोज़्ड होना चाहिए या लॉगिन/कार्रवाई स्थिति लौटानी चाहिए; फ़ीड का टाइमआउट शैल को उपयोग योग्य बनाए रख सकता है। RFC 9457 का पालन करने वाला एक त्रुटि ऑब्जेक्ट यह दिखाए बिना कि प्रत्येक अनुभाग विफल रहा, संपूर्ण-अनुरोध विफलताओं का वर्णन कर सकता है।

3. पुनः प्रयासों और आउटेज से डिपेंडेंसीज़ को सुरक्षित रखें

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

4. कॉन्ट्रैक्ट को विकसित और मॉनिटर करें

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

एक सशक्त नमूना उत्तर

मैं फ्रेशनेस और प्रोग्रेसिव रेंडरिंग की अनुमति है या नहीं, इसे स्पष्ट करूँगा। गेटवे एक बार प्रमाणित करता है, तीन रीड्स को फैन आउट करता है, और 300 ms के समग्र बजट के भीतर प्रति-कॉल समय सीमा निर्दिष्ट करता है। यह अनुभाग-स्तरीय ready, stale, या unavailable स्थितियाँ लौटाता है। आवश्यक पहचान और अनुमतियाँ फेल-क्लोज़्ड होती हैं; फ़ीड डेटा एक सीमित बासी कैश से आ सकता है। केवल क्षणिक आइडम्पोटेंट रीड्स के लिए एक जिटर वाले पुनः प्रयास की अनुमति है, जो एक डिपेंडेंसी बल्कहेड और सर्किट ब्रेकर द्वारा सुरक्षित है। मेट्रिक्स और ट्रेस अनुभाग विफलताओं और समय सीमा के दबाव को उजागर करते हैं, जबकि योगात्मक वर्शनिंग पुराने क्लाइंट्स को काम करना जारी रखने की अनुमति देती है।

सामान्य गलतियाँ

  • डिपेंडेंसीज़ को क्रमिक रूप से कॉल करना → लेटेंसी बजट से अधिक बढ़ जाती है → सीमित पूल और समय सीमा के साथ फैन आउट करें।
  • अस्पष्ट nulls के साथ HTTP 200 लौटाना → क्लाइंट खाली डेटा और विफलता के बीच अंतर नहीं कर पाता है → स्पष्ट अनुभाग स्थिति और कारण कोड का उपयोग करें।
  • प्रत्येक परत में प्रत्येक त्रुटि का पुनः प्रयास करना → एक आउटेज पुनः प्रयास के तूफान (retry storm) में बदल जाता है → त्रुटियों को वर्गीकृत करें और एक साझा पुनः प्रयास बजट लागू करें।
  • बिना नीति के अनुमतियों को कैश करना → एक्सेस अपने प्राधिकरण से अधिक समय तक बना रह सकता है → फ्रेशनेस सीमा परिभाषित करें या फेल-क्लोज़्ड करें।
  • एक ही ग्लोबल सर्किट का उपयोग करना → फ़ीड आउटेज पहचान डेटा को ब्लॉक कर देता है → सर्किट ब्रेकर्स और बल्कहेड्स को डिपेंडेंसी के अनुसार अलग करें।
  • केवल कुल लेटेंसी लॉग करना → वैकल्पिक और आवश्यक विफलताएं अप्रभेद्य हो जाती हैं → अनुभाग-स्तरीय मेट्रिक्स और ट्रेस उत्सर्जित करें।

अनुवर्ती प्रश्न और उत्तर

फ़ीड धीमी है लेकिन उपयोगकर्ता को तुरंत शैल की आवश्यकता है। क्या बदलाव होंगे?

फ़ीड की समय सीमा कम करें, जब आयु स्वीकार्य हो तो एक सीमित बासी परिणाम प्रदान करें, अन्यथा unavailable लौटाएं। शैल प्रतिक्रिया को स्वतंत्र रखें ताकि क्लाइंट बाद में फ़ीड लोड कर सके।

एक क्षेत्र में अनुमतियों का डेटा बासी है। क्या आप इसे सर्व कर सकते हैं?

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

आप पुनः प्रयास को 300 ms से आगे बढ़ने से कैसे रोकते हैं?

फैन-आउट संदर्भ के माध्यम से एक पूर्ण समय सीमा (absolute deadline) पास करें। प्रत्येक पुनः प्रयास से पहले, प्रयास और असेंबली के लिए समय आरक्षित करें; यदि कोई समय शेष नहीं है, तो ऐसा कार्य शुरू करने के बजाय जो समाप्त नहीं हो सकता, अनुभाग की टाइमआउट स्थिति लौटाएं।

सर्किट खुलने के बाद डिपेंडेंसी ठीक हो जाती है। ट्रैफ़िक कैसे पुनर्स्थापित किया जाता है?

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

सार्वजनिक स्रोत

संबंधित प्रश्न

संबंधित इंटरव्यू टूल

सिस्टम डिज़ाइन उत्तर के लिए हल करें का उपयोग करें

पहले आवश्यकताओं को स्पष्ट करें, फिर स्केल, आर्किटेक्चर, कंपोनेंट चयन और ट्रेड-ऑफ की ओर बढ़ें।

टूल देखें