टीएल;डीआर

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

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

यह पोस्ट वही डिज़ाइन शून्य से सिखाता है। पहले इंटरव्यू वाली जटिल भाषा नहीं। सादा टुकड़े, फिर एक पूरा रास्ता: "ऑर्डर शिप हो गया" से लेकर फ़ोन के कंपन तक।


हम कौन-सी समस्या हल कर रहे हैं?

किसी ऐप के पास किसी व्यक्ति से बात करने की कई वजहें होती हैं:

  • आपका पार्सल गोदाम से निकल गया।
  • यह रहा आपका लॉगिन कोड।
  • आपके कार्ड से पैसे कटे।
  • किसी दोस्त ने आपकी फ़ोटो पसंद की।

ये इवेंट हैं। नोटिफिकेशन सिस्टम इवेंट को उन संदेशों में बदलता है जिन्हें लोग देख सकें: फ़ोन पर पुश, एसएमएस, या ईमेल। बाक़ी प्रोडक्ट सेवाओं को खुद से टेक्स्ट और ईमेल का सिस्टम नहीं बनाना चाहिए। वे नोटिफिकेशन सिस्टम से कहते हैं "इस यूज़र को इस इवेंट की सूचना दो," और बाक़ी काम सिस्टम करता है।

स्कूल की तस्वीर में:

स्कूल दफ़्तर नोटिफिकेशन सिस्टम
छात्र के बारे में ख़बर प्रोडक्ट इवेंट (ऑर्डर शिप, पासवर्ड रीसेट)
माता-पिता का संपर्क कार्ड यूज़र प्रोफ़ाइल (ईमेल, फ़ोन, डिवाइस टोकन)
"सिर्फ़ इमरजेंसी में कॉल" नियम यूज़र प्राथमिकताएँ (ऑप्ट-इन / ऑप्ट-आउट)
ख़ाली जगहों वाला फ़ॉर्म लेटर टेम्पलेट
रनर का इंतज़ार करती आउटबॉक्स ट्रे कतार (queue)
डायल या मेल करने वाला रनर वर्कर जो ऐपल, एसएमएस या ईमेल प्रोवाइडर से बात करता है
लाइन व्यस्त हो तो फिर कोशिश रिट्राई

चैनल: तीन दरवाज़े जिनसे संदेश निकलते हैं

चैनल बस यही है कि संदेश कैसे पहुँचेगा।

१. पुश

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

स्कूल तस्वीर: माता-पिता के फ़ोन पर छोटी नोट, पूरी चिट्ठी नहीं।

२. एसएमएस

फ़ोन नंबर पर टेक्स्ट। आप गेटवे कंपनी (ट्विलियो जैसी) को पैसे देते हैं। वे कैरियर से बात करते हैं। एसएमएस महँगा है और अक्सर कोड व ज़रूरी अलर्ट के लिए इस्तेमाल होता है।

स्कूल तस्वीर: माता-पिता के नंबर पर असली टेक्स्ट।

३. ईमेल

इनबॉक्स में लंबा संदेश। ज़्यादातर टीमें ईमेल प्लेटफ़ॉर्म (सेंडग्रिड, Amazon SES, मेलगन) इस्तेमाल करती हैं ताकि बाउंस और रेपुटेशन खुद न संभालना पड़े।

स्कूल तस्वीर: माता-पिता के ईमेल बॉक्स में पूरी चिट्ठी।

डिज़ाइन नियम: हर चैनल एक जैसा आकार: कतार → वर्कर → बाहरी प्रोवाइडर। एक दिमाग़, अलग-अलग संदेशवाहक।

आख़िरी मील लगभग कभी आपका नहीं होता। ऐपल, कैरियर और ईमेल नेटवर्क करते हैं। आपका काम सही तरीके से माँगना, याद रखना कि क्या माँगा, और जब वे फेल हों तो संभलना।


प्राथमिकताएँ: जिसने मना किया उसे मत भेजो

अगर स्कूल हर दिन लंच मेनू का टेक्स्ट भेजे तो माता-पिता नाराज़ होते हैं। स्पैम करने वाली ऐप्स यूज़र म्यूट कर देते हैं। इसलिए सिस्टम प्राथमिकताएँ रखता है:

  • चैनल: पुश हाँ, एसएमएस नहीं, ईमेल हाँ।
  • श्रेणी: सुरक्षा हाँ, मार्केटिंग नहीं, प्रोडक्ट टिप्स हाँ।
  • शांत घंटे: यूज़र के टाइमज़ोन में रात २ बजे मार्केटिंग नहीं।

भेजने से पहले दफ़्तर कार्ड देखता है:

१. इस यूज़र, चैनल और श्रेणी की सेटिंग लोड करो। २. ऑप्ट-आउट हो तो छोड़ दो। ३. सुरक्षा के अलावा ख़बरों पर शांत घंटे मानो। ४. सुरक्षा और पैसे वाले संदेश (पासवर्ड रीसेट, पेमेंट फेल) अक्सर मार्केटिंग बंद होने पर भी जाते हैं। यह प्रोडक्ट और क़ानून तय करते हैं। साफ़ बोलो।

प्राथमिकताएँ सिर्फ़ शिष्टाचार नहीं। भरोसा और ईमेल डिलीवरेबिलिटी बचाती हैं। जो सिस्टम म्यूट न माने, वह टूटा सिस्टम है।


टेम्पलेट: ख़ाली जगहों वाले फ़ॉर्म लेटर

आप नहीं चाहेंगे कि हर टीम अपनी सेवा में कच्चा एचटीएमएल ईमेल लिखे। नोटिफिकेशन सिस्टम टेम्पलेट रखता है: मंज़ूर टेक्स्ट, ख़ाली जगहों के साथ।

पुश टेम्पलेट का उदाहरण:

आपका ऑर्डर {{order_id}} शिप हो गया। ट्रैक करें: {{tracking_url}}

भेजते समय सिस्टम ख़ाली जगह भरता है: ऑर्डर आईडी, नाम, राशि, लिंक।

टेम्पलेट होने चाहिए:

  • चैनल के अनुसार (पुश छोटा; ईमेल लंबा एचटीएमएल; एसएमएस में अक्षरों की सीमा)।
  • भाषा के अनुसार अगर कई लोकल हैं।
  • वर्जन वाले ताकि ख़राब एडिट वापस लिया जा सके।
  • सुरक्षित: यूज़र नियंत्रित टेक्स्ट एस्केप करो ताकि अजीब नाम एचटीएमएल न तोड़े।

स्कूल तस्वीर: फ़ॉर्मों का ढेर। स्टाफ़ हर कॉल पर क़ानूनी वाक्य खुद नहीं गढ़ता।


कतारें: आउटबॉक्स ट्रे

अगर प्रिंसिपल हर कैरियर पर होल्ड पर बैठे रहें और काउंटर पर माता-पिता जमा होते रहें, तो पूरा दफ़्तर रुक जाता है। सॉफ़्टवेयर में भी वैसा ही।

कतार काम की प्रतीक्षा पंक्ति है:

१. कुछ ज़रूरी होता है (ऑर्डर शिप)। २. नोटिफिकेशन एपीआई इरादा दर्ज करती है और कतार में जॉब डालती है। ३. तुरंत "स्वीकार" जवाब देती है (एचटीटीपी २०२ जैसा)। ४. अलग वर्कर जॉब निकालकर ऐपल, एसएमएस या ईमेल से बात करते हैं।

कतारें क्यों ज़रूरी:

  • भीड़ (बड़ी सेल, कैंपेन) ट्रे में गिरती है, एपीआई को कुचलती नहीं।
  • एसएमएस डाउन हो तो पुश न रुके। हर चैनल की अपनी कतार रखो।
  • फेल जॉब इंतज़ार करके फिर कोशिश कर सकते हैं, बिना मूल सेवा को लटकाने।
[ ऑर्डर सेवा ]
       |
       v
[ नोटिफिकेशन एपीआई ]
  यूज़र, प्राथमिकता, टेम्पलेट जाँच
  लॉग पंक्ति लिखो
       |
       +---> [ पुश कतार ]  --> पुश वर्कर  --> ऐपल / गूगल
       |
       +---> [ एसएमएस कतार ] --> एसएमएस वर्कर --> एसएमएस प्रोवाइडर
       |
       +---> [ ईमेल कतार ] --> ईमेल वर्कर --> ईमेल प्रोवाइडर

स्वीकार और डिलीवर को अलग रखो। स्वीकार मतलब "हमने लिख लिया और ट्रे में डाल दिया।" डिलीवर मतलब "बाहर की दुनिया को मिल गया।" ये दो कदम हैं।


रिट्राई: फिर कोशिश, लेकिन हमेशा नहीं

नेटवर्क फेल होते हैं। प्रोवाइडर "व्यस्त" कहते हैं। फ़ोन ऑफ़लाइन होते हैं। इसलिए वर्कर रिट्राई करते हैं।

सादे नियम:

क्या गड़बड़ क्या करें
अस्थायी गलती (टाइमआउट, ५०३) हर बार ज़्यादा इंतज़ार (backoff), फिर कोशिश
ख़राब टोकन या मरा ईमेल स्थायी फेल; उस गंतव्य पर रुक जाओ
प्रोवाइडर रेट लिमिट धीमे चलो; देरी के साथ कतार में वापस
ज़हरीला संदेश (टूटा टेम्पलेट डेटा) N कोशिश के बाद डेड-लेटर कतार और इंसानों को अलर्ट

कोशिशों की सीमा रखो। टूटे टेम्पलेट पर अनंत रिट्राई आपके प्रोवाइडर बिल पर आत्म-हमला बन जाती है।

और: दुनिया कम-से-कम एक बार (at-least-once) है, बिल्कुल एक बार (exactly-once) नहीं। टाइमआउट से आप अनिश्चित रह सकते हैं कि एसएमएस निकल चुका या नहीं। कॉलर को इडेम्पोटेंसी कुंजी भेजनी चाहिए (एक यूनिक आईडी: "हमने यह रसीद एक बार माँग ली")। सिस्टम उसे याद रखता है और एक विंडो में सटीक डुप्लिकेट हटाता है। लोग खोया पासवर्ड रीसेट दुर्लभ डबल पुश से ज़्यादा नफ़रत करते हैं, फिर भी जहाँ हो सके मज़बूत डेडुप करो।


संपर्क डेटा जो रखना ज़रूरी है

पते बिना कुछ भवन से बाहर नहीं जाता।

डेटा क्यों
ईमेल, फ़ोन ईमेल और एसएमएस के गंतव्य
डिवाइस पुश टोकन एक यूज़र के कई फ़ोन; टोकन ख़त्म होते हैं
भाषा और टाइमज़ोन भाषा और शांत घंटे
प्राथमिकताएँ चैनल और श्रेणी के स्विच
नोटिफिकेशन लॉग क्या कोशिश की, स्टेटस, प्रोवाइडर आईडी

टोकन ऐप इंस्टॉल या लॉगिन पर आते हैं। जब ऐपल या गूगल कहें टोकन हमेशा के लिए मरा है, उसे निष्क्रिय करो। कभी न मानो कि एक फ़ोन हमेशा रहेगा।


एक इवेंट का सफ़र: ऑर्डर शिप → फ़ोन कंपन

एक कहानी शुरू से अंत तक।

दृश्य: गोदाम सिस्टम यूज़र cus_12 के लिए ऑर्डर ord_9f3a को शिप मार्क करता है। प्रोडक्ट पुश और ईमेल चाहता है। यूज़र ने मार्केटिंग एसएमएस बंद किया है, लेकिन यह ट्रांज़ैक्शनल शिपिंग अपडेट है।

कदम १: इवेंट

ऑर्डर सेवा नोटिफिकेशन सेवा को कॉल करती है:

POST /internal/v1/notifications

{
  "idempotency_key": "ord_9f3a:shipped:v1",
  "user_id": "cus_12",
  "template_id": "order_shipped",
  "channels": ["email", "push"],
  "category": "transactional",
  "data": {
    "order_id": "ord_9f3a",
    "tracking_url": "https://shop.example/t/abc"
  }
}

सिर्फ़ भरोसेमंद आंतरिक सेवाएँ यह कॉल करें। ऐपल और एसएमएस के सीक्रेट सीक्रेट स्टोर में रहें, चैट या बिखरी कॉन्फ़िग में नहीं।

कदम २: दफ़्तर अभिभावक कार्ड जाँचता है

नोटिफिकेशन एपीआई:

१. कॉलर को प्रमाणित करती है। २. देखती है कि वही इडेम्पोटेंसी कुंजी पहले से पूरी तरह हैंडल तो नहीं। ३. ईमेल, डिवाइस, प्राथमिकताएँ और order_shipped टेम्पलेट लोड करती है। ४. एसएमएस छोड़ती है (माँगा नहीं)। सेटिंग अनुमति दें तो ईमेल और पुश रखती है। ५. रेट लिमिट जाँचती है ताकि एक सेवा यूज़र पर बाढ़ न लाए या एसएमएस बजट न जलाए। ६. नोटिफिकेशन लॉग में pending स्टेटस वाली पंक्ति लिखती है (इरादा दर्ज)। ७. एक ईमेल जॉब और एक पुश जॉब कतार में डालती है (या हर सक्रिय डिवाइस के लिए पुश)। ८. notification_id के साथ 202 Accepted लौटाती है। ऑर्डर सेवा ऐपल का इंतज़ार नहीं करती।

स्कूल तस्वीर: स्टाफ़ फ़ॉर्म पर मोहर लगाता है, स्लिप ट्रे में डालता है, गोदाम से कहता है "हमें मिल गया।"

कदम ३: ईमेल वर्कर

१. ईमेल कतार से जॉब निकालता है। २. ऑर्डर आईडी और ट्रैकिंग लिंक से टेम्पलेट भरता है। ३. ईमेल प्रोवाइडर को कॉल करता है। ४. प्रोवाइडर का मैसेज आईडी सहेजता है। ५. लॉग sent (या कारण सहित failed) करता है।

कदम ४: पुश वर्कर (फ़ोन तक का रास्ता)

१. पुश जॉब निकालता है। २. cus_12 के सक्रिय डिवाइस टोकन ढूँढता है। ३. पुश टेम्पलेट से छोटा पेलोड बनाता है। ४. हर टोकन के लिए एपीएनएस या एफसीएम पर पोस्ट करता है। ५. "टोकन अमान्य" पर उस डिवाइस पंक्ति को निष्क्रिय करता है। ६. अस्थायी गलती पर backoff के साथ रिट्राई। ७. लॉग अपडेट करता है।

कदम ५: फ़ोन

डिवाइस ऑनलाइन हो तो ऐपल या गूगल डिलीवर करते हैं। यूज़र देखता है: "आपका ऑर्डर ord_९f३a शिप हो गया..." वैकल्पिक डीप लिंक ट्रैकिंग खोलता है।

कदम ६: बाद में रसीदें

प्रोवाइडर वेबहुक भेज सकते हैं: डिलीवर, बाउंस, ओपन। वे एनालिटिक्स अपडेट करते हैं, मूल सेंड पथ को नहीं रोकते। गर्म रास्ता पतला रहता है।

पूरी रीढ़ यही है: इवेंट → प्राथमिकता जाँच → इरादा दर्ज → कतार → वर्कर → प्रोवाइडर → डिवाइस


एक डिज़ाइन जो आप बचा सकें (इंटरव्यू आकार)

अगर व्हाइटबोर्ड पर पूछे जाएँ, बोलो:

१. स्टेटलेस नोटिफिकेशन एपीआई auth, वैलिडेशन, प्राथमिकता, रेट लिमिट और इडेम्पोटेंसी के लिए। २. डेटाबेस + कैश यूज़र, डिवाइस, सेटिंग, टेम्पलेट और लॉग के लिए। ३. हर चैनल की कतार और वर्कर पुश, एसएमएस, ईमेल एडाप्टर के साथ। ४. टेम्पलेट वर्कर में रेंडर, वर्जन और भाषा सहित। ५. कम-से-कम एक बार डिलीवरी: रिट्राई, डेड-लेटर कतार, इडेम्पोटेंसी कुंजी। ६. मॉनिटरिंग कतार की उम्र और प्रोवाइडर त्रुटि दर पर।

ज़ोर से बोलने योग्य समझौते:

  • एक साझा कतार आसान; चैनल-वार कतारें फेलियर अलग रखती हैं।
  • सिंक सेंड डिबग आसान और प्रोवाइडर धीमे होने पर मर जाता है।
  • कैरियर पर बिल्कुल-एक-बार मुफ़्त नहीं; इडेम्पोटेंसी और डेडुप व्यावहारिक बार।
  • मार्केटिंग ब्लास्ट और पासवर्ड कोड एक ही प्राथमिकता और बजट न बाँटें।
  • खुद का ईमेल सर्वर सस्ता लगता है जब तक रेपुटेशन टीम न खा जाए।

मोटा स्केल उदाहरण (इंटरव्यूअर से मिलाकर): दिन में लाखों पुश, कम एसएमएस क्योंकि पैसा लगता है, सॉफ़्ट रियल-टाइम (शिपिंग के लिए सेकंड ठीक; ओटीपी के लिए तेज़ प्राथमिकता पथ)।


दोस्त के लिए सार

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


समापन

स्कूल दफ़्तर अच्छी तरह बनाओ: चैनल दरवाज़ों के लिए, प्राथमिकताएँ सहमति के लिए, टेम्पलेट एक जैसी भाषा के लिए, कतारें ताकि काउंटर न जमे, और रिट्राई ताकि अस्थायी फेल हमेशा की चुप्पी न बने। स्वीकार और डिलीवर अलग रखो। चैनल अलग-थलग रखो। बाहरी प्रोवाइडर को अविश्वसनीय सहकर्मी मानो। बाक़ी सब उसी रीढ़ से लटकता है।