30 मार्च 2025·8 मिनट पढ़ने में

वेबहुक विश्वसनीयता चेकलिस्ट: रिट्राइज़, आइडेम्पोटेंसी और रिप्ले

व्यावहारिक वेबहुक विश्वसनीयता चेकलिस्ट: रीट्राइज़, आइडेम्पोटेंसी, रिप्ले लॉग और मॉनिटरिंग—इनबाउंड और आउटबाउंड वेबहुक के लिए जब पार्टनर फेल करें।

वेबहुक विश्वसनीयता चेकलिस्ट: रिट्राइज़, आइडेम्पोटेंसी और रिप्ले

असली प्रोजेक्ट्स में वेबहुक भरोसेमंद क्यों नहीं लगते

वेबहुक एक साधारण तरीका है: एक सिस्टम दूसरे सिस्टम को HTTP रिक्वेस्ट भेजता है जब कुछ होता है। "Order shipped", "ticket updated", "device went offline"। यह मूल रूप से ऐप्स के बीच एक पुश नोटिफिकेशन है, जो वेब पर दिया जाता है।

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

पहले संकेत आमतौर पर भ्रमित करने वाले होते हैं:

  • डुप्लिकेट ईवेंट्स (वही अपडेट दो बार आना)
  • गायब ईवेंट्स (कुछ बदल गया पर आपको कभी सूचना नहीं मिली)
  • देरी (अपडेट मिनट या घंटे बाद आता है)
  • ईवेंट्स का क्रम बिगड़ना ("closed" अपडेट "opened" से पहले आना)

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

कल्पना कीजिए एक शिपिंग पार्टनर जो "delivered" वेबहुक भेजता है। एक दिन आपका रिसीवर 3 सेकंड के लिए धीमा हो जाता है, तो वे रीट्राइ कर देते हैं। आपको दो "delivered" मिलते हैं, आपके ग्राहक को दो ईमेल जाते हैं, और सपोर्ट कन्फ्यूज़ हो जाता है। अगले दिन उनका आउटेज होता है और वे कभी रीट्राइ नहीं करते, इसलिए "delivered" कभी नहीं आता और आपका डैशबोर्ड फंस जाता है।

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

तीन आधार स्तम्भ: रीट्राइज़, आइडेम्पोटेंसी, रिप्ले

वेबहुक दोनों दिशाओं में आते हैं। इनबाउंड वेबहुक वे कॉल हैं जिन्हें आप किसी और से प्राप्त करते हैं (पेमेन्ट प्रोवाइडर, CRM, शिपिंग टूल)। आउटबाउंड वेबहुक वे कॉल हैं जो आप अपने ग्राहक या पार्टनर को तब भेजते हैं जब आपके सिस्टम में कुछ बदलता है। दोनों किसी भी कारण से फेल हो सकते हैं जो आपके कोड से संबंधित नहीं है।

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

आइडेम्पोटेंसी वो तरीका है जिससे आप डुप्लिकेट्स को सुरक्षित बनाते हैं। इसका मतलब है "एक बार करो, भले ही दो बार मिल जाए"। अगर वही वेबहुक फिर से आता है, आप उसे पहचानते हैं और सफल प्रतिक्रिया लौटाते हैं बिना बिजनेस एक्शन को दूसरी बार चलाए (उदाहरण के लिए, दूसरी इनवॉइस न बनाएं)।

रिप्ले आपका रिकवरी बटन है। यह नियंत्रित तरीके से पिछले ईवेंट्स को जानबूझकर फिर से प्रोसेस करने की क्षमता है, किसी बग को ठीक करने के बाद या पार्टनर के आउटेज के बाद। रिप्ले रीट्राइ से अलग है: रीट्राइ स्वचालित और तुरंत होते हैं, रिप्ले जानबूझकर और अक्सर घंटे या दिनों बाद होता है।

अगर आप वेबहुक विश्वसनीयता चाहते हैं, तो कुछ सरल लक्ष्य तय करें और उनके इर्द-गिर्द डिज़ाइन करें:

  • कोई खोया हुआ ईवेंट नहीं (आप हमेशा पा सकें कि क्या आया या आपने क्या भेजने की कोशिश की)
  • सुरक्षित डुप्लिकेट्स (रीट्राइज़ और रिप्ले से डबल-चार्ज, डबल-क्रिएट, या डबल-ईमेल नहीं हों)
  • स्पष्ट ऑडिट ट्रेल (आप जल्दी से जवाब दे सकें: "क्या हुआ?")

तीनों को सपोर्ट करने का व्यावहारिक तरीका है हर वेबहुक प्रयास को स्टेटस और एक यूनिक idempotency की के साथ स्टोर करना। कई टीमें इसे एक छोटा "वेबहुक इनबॉक्स/आउटबॉक्स" टेबल के रूप में बनाती हैं।

इनबाउंड वेबहुक: एक रिसीवर फ्लो जिसे आप रीयूज़ कर सकते हैं

अधिकांश वेबहुक समस्याएँ इसलिए होती हैं क्योंकि भेजने वाला और रिसीवर अलग क्लॉक पर चलते हैं। रिसीवर के रूप में आपका काम predictable होना है: जल्दी acknowledge करें, जो आया उसे रिकॉर्ड करें, और इसे सुरक्षित रूप से प्रोसेस करें।

"अक्जेप्ट" को "वर्क करें" से अलग करें

एक ऐसा फ्लो शुरू करें जो HTTP रिक्वेस्ट को तेज़ रखे और असली काम को कहीं और भेज दे। इससे टाइमआउट्स कम होते हैं और रीट्राइज़ बहुत कम दर्दनाक बनते हैं।

  • जल्दी स्वीकार करें। जैसे ही रिक्वेस्ट स्वीकार्य लगे, 2xx लौटाएँ।
  • बेसिक्स चेक करें। कंटेंट-टाइप, आवश्यक फ़ील्ड्स और पार्सिंग वैलिडेट करें। अगर वेबहुक साइन किया हुआ है, तो यहाँ सिग्नेचर वेरिफ़ाई करें।
  • रॉ ईवेंट पर्सिस्ट करें। बॉडी के साथ वे हेडर्स स्टोर करें जिनकी बाद में जरूरत होगी (signature, event ID), प्राप्ति टाइमस्टैंप और एक स्टेटस जैसे "received" के साथ।
  • वर्क को कतार में डालें। बैकग्राउंड प्रोसेसिंग के लिए एक जॉब बनाएं, फिर 2xx रिटर्न करें।
  • स्पष्ट परिणामों के साथ प्रोसेस करें। केवल तभी ईवेंट को "processed" मार्क करें जब साइड-इफेक्ट्स सफल हों। अगर फेल होता है, तो कारण रिकॉर्ड करें और यह रिकॉर्ड करें कि क्या इसे रीट्राइ करना चाहिए।

"तेज़ जवाब दें" कैसा दिखता है

एक वास्तविक लक्ष्य है कि एक सेकंड से कम में जवाब दें। अगर भेजने वाला किसी विशेष कोड की उम्मीद करता है, तो वही प्रयोग करें (कई 200 स्वीकारते हैं, कुछ 202 पसंद करते हैं)। केवल तब 4xx लौटाएँ जब भेजने वाले को रीट्राइ नहीं करनी चाहिए (जैसे invalid signature)।

उदाहरण: एक "customer.created" वेबहुक तब आता है जब आपका डेटाबेस लोड में है। इस फ्लो के साथ आप अभी भी रॉ ईवेंट स्टोर कर लेंगे, उसे एनक्यू करेंगे, और 2xx लौटाएँगे। आपका वर्कर बाद में रीट्राइ कर सकता है बिना भेजने वाले को फिर से भेजने की जरूरत के।

इनबाउंड सेफ़्टी चेक्स जो डिलिवरी नहीं तोड़ते

सिक्योरिटी चेक्स करने लायक हैं, पर लक्ष्य सरल है: बुरा ट्रैफ़िक ब्लॉक करना बिना असली ईवेंट्स ब्लॉक किए। बहुत सी डिलीवरी समस्याएँ रिसीवर्स बहुत सख्त होने या गलत प्रतिक्रिया लौटाने के कारण आती हैं।

शुरुआत करें भेजने वाले को साबित करने से। साइन किए गए रिक्वेस्ट (HMAC सिग्नेचर हेडर) या हेडर में शेयर किया गया सीक्रेट टोकन पसंद करें। इसे भारी काम करने से पहले वेरिफ़ाई करें, और अगर यह गायब या गलत हो तो फेल फ़ास्ट करें।

स्टेटस कोड्स के साथ सावधान रहें क्योंकि वे रीट्राइज़ को नियंत्रित करते:

  • ऑथ फेलियर के लिए 401/403 लौटाएँ ताकि भेजने वाला अनंत काल तक रीट्राइ न करे।
  • खराब JSON या आवश्यक फ़ील्ड्स के गायब होने पर 400 लौटाएँ।
  • केवल तब 5xx लौटाएँ जब आपकी सर्विस अस्थायी रूप से स्वीकार या प्रोसेस नहीं कर सकती।

IP allowlists मददगार हो सकती हैं, पर केवल तभी जब प्रोवाइडर के पास स्थिर, डॉक्यूमेंटेड IP रेंज हों। अगर उनके IP अक्सर बदलते हैं (या वे बड़े क्लाउड पूल का उपयोग करते हैं), तो allowlists असल वेबहुक्स को चुपचाप ड्रॉप कर सकती हैं और आप बाद में ही नोटिस कर पाएँगे।

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

एक रिसीवर-फ्रेंडली सिक्योरिटी चेकलिस्ट:

  • बड़े पेलोड पार्स करने से पहले सिग्नेचर या शेयर किए गए सीक्रेट को वेरिफ़ाई करें।
  • अधिकतम बॉडी साइज लागू करें और छोटा रिक्वेस्ट टाइमआउट रखें।
  • ऑथ फेलियर के लिए 401/403, खराब JSON के लिए 400 और स्वीकार किए गए ईवेंट के लिए 2xx उपयोग करें।
  • अगर आप टाइमस्टैम्प चेक करते हैं, तो एक छोटा ग्रेस विंडो दें (उदाहरण के लिए, कुछ मिनट)।

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

ऐसे रीट्राइज़ जो मदद करें, नुकसान नहीं पहुँचाएँ

रिप्ले को नियमित ठीक-ठाक प्रक्रिया बनाएं
इंटरनल एडमिन पैनल बनाकर फेल्ड ईवेंट्स को सुरक्षित तरीके से निरीक्षण, रिप्ले और हल करें।
अब बनाएं

रीट्राइज़ तब अच्छे हैं जब वे एक छोटी हिचकी को सफल डिलीवरी में बदल दें। वे हानिकारक तब होते हैं जब वे ट्रैफ़िक को गुणा कर दें, असली बग्स छिपा दें, या डुप्लिकेट्स पैदा करें। फर्क ये है कि क्या रीट्राइ के लिए स्पष्ट नियम हैं, उन्हें कैसे स्पेस किया जाता है, और कब रोकना है।

आमतौर पर, केवल उन चीज़ों पर रीट्राइ करें जहाँ रिसीवर बाद में सफल होने की संभावना रखता हो। एक उपयोगी मानसिक मॉडल है: "टेम्पररी" फेलियर पर रीट्राइ करें, "आपने कुछ ग़लत भेजा" पर नहीं।

प्रैक्टिकल HTTP परिणाम:

  • रीट्राइ करें: नेटवर्क टाइमआउट्स, कनेक्शन एरर्स, और HTTP 408, 429, 500, 502, 503, 504
  • रीट्राइ न करें: HTTP 400, 401, 403, 404, 422
  • निर्भर करता है: HTTP 409 (कभी-कभी "डुप्लिकेट", कभी-कभी असली संघर्ष)

स्पेसिंग मायने रखती है। exponential backoff के साथ jitter का उपयोग करें ताकि कई ईवेंट्स एक साथ फेल होने पर retry storm न बनें। उदाहरण के लिए: 5s, 15s, 45s, 2m, 5m, और हर बार थोड़ा रैंडम ऑफ़सेट जोड़ें।

एक अधिकतम रीट्राइ विंडो और स्पष्ट cutoff भी सेट करें। सामान्य विकल्प हैं "24 घंटे तक कोशिश करते रहें" या "10 प्रयासों से अधिक नहीं"। उसके बाद इसे रिकवरी प्रॉबलम समझें, न कि डिलीवरी प्रॉबलम।

काम करने के लिए, आपका ईवेंट रिकॉर्ड निम्न कैप्चर करे:

  • प्रयासों की गिनती
  • आखिरी त्रुटि
  • अगला प्रयास समय
  • अंतिम स्टेटस (और जब आप रीट्राइ बंद कर दें तो dead-letter स्टेट)

डेड-लैटर आइटम्स को आसानी से निरीक्षित और सुरक्षित रूप से फिर से चलाने योग्य होना चाहिए जब आप मूल समस्या ठीक कर लें।

प्रैक्टिकल आइडेम्पोटेंसी पैटर्न

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

एक ऐसी की चुनें जो स्थिर रहे

अगर प्रोवाइडर आपको ईवेंट ID देता है, तो उसे उपयोग करें। यह सबसे साफ़ तरीका है।

अगर कोई ईवेंट ID नहीं है, तो स्थिर फ़ील्ड्स से अपनी की बनाएं, जैसे:

  • provider name + event type + resource ID + timestamp का हैश, या
  • provider name + message ID

की के साथ थोड़ा मेटाडाटा स्टोर करें (रिसीव टाइम, प्रोवाइडर, ईवेंट टाइप और रिज़ल्ट)।

सामान्य नियम जो अक्सर काम आते हैं:

  • की को अवश्यक मानें। अगर आप की नहीं बना सकते, तो ईवेंट को क्वारंटीन करें बजाय अनुमान लगाने के।
  • कीज़ को TTL के साथ स्टोर करें (उदाहरण के लिए 7 से 30 दिन) ताकि टेबल अनंत तक न बढ़े।
  • प्रोसेसिंग रिज़ल्ट भी सेव करें (success, failed, ignored) ताकि डुप्लिकेट्स को सुसंगत प्रतिक्रिया मिले।
  • की पर यूनिक कंस्ट्रेंट रखें ताकि दो समानांतर रिक्वेस्ट दोनों रन न करें।

बिजनेस एक्शन को भी आइडेम्पोटेंट बनाएं

एक अच्छी की टेबल होने के बावजूद, आपके असली ऑपरेशन्स को सुरक्षित होना चाहिए। उदाहरण: एक "create order" वेबहुक को दूसरी बार चलाकर दूसरा ऑर्डर नहीं बनाना चाहिए अगर पहली कोशिश टाइमआउट के बाद डेटाबेस इन्सर्ट हो गया था। नेचुरल बिजनेस आईडेंटिफायर्स (external_order_id, external_user_id) और upsert पैटर्न का उपयोग करें।

आउट-ऑफ-ऑर्डर ईवेंट्स सामान्य हैं। अगर आप "user_updated" को "user_created" से पहले पाते हैं, तो एक नियम तय करें जैसे "केवल तब बदलाव लागू करें जब event_version नया हो" या "केवल तब अपडेट करें जब updated_at हमारे पास मौजूद से बाद का हो"।

विभिन्न पेलोड्स के साथ डुप्लिकेट्स सबसे कठिन केस हैं। पहले से तय करें कि आप क्या करेंगे:

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

लक्ष्य सरल है: एक वास्तविक दुनिया परिवर्तन को एक वास्तविक दुनिया परिणाम देना चाहिए, भले ही आप संदेश तीन बार देखें।

रिप्ले टूल्स और ऑडिट लॉग्स फ़ॉर रिकवरी

डिलीवरी को बिगाड़े बिना सिक्योरिटी संभालें
डिलिवरी रोकें बिना सिग्नेचर चेक और स्टेटस-कोड नियम लागू करें।
AppMaster आज़माएँ

जब पार्टनर सिस्टम अस्थिर हो, तो विश्वसनीयता परफेक्ट डिलीवरी के बजाय तेज़ रिकवरी के बारे में अधिक होती है। एक रिप्ले टूल "हमने कुछ ईवेंट खो दिए" को संकट की बजाय नियमित ठीक करने वाली प्रक्रिया बना देता है।

शुरू करें एक ईवेंट लॉग से जो हर वेबहुक का लाइफसाइकल ट्रैक करे: received, processed, failed, या ignored। इसे समय, ईवेंट टाइप और correlation ID से सर्चेबल रखें ताकि सपोर्ट जल्दी से जवाब दे सके: "Order 18432 को क्या हुआ?"।

प्रत्येक ईवेंट के लिए इतना संदर्भ स्टोर करें कि उसे बाद में वही निर्णय फिर से चलाने लायक बनाया जा सके:

  • रॉ पेलोड और की-हेडर्स (signature, event ID, timestamp)
  • आपने जो सामान्यीकृत फ़ील्ड्स निकालीं
  • प्रोसेसिंग रिज़ल्ट और एरर मैसेज (अगर कोई हो)
  • उस समय उपयोग किए गए वर्कफ़्लो या मैपिंग वर्शन
  • receive, start, finish के टाइमस्टैम्प

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

ऐसे गार्डरेल्स जो आकस्मिक नुकसान रोकें:

  • रिप्ले से पहले एक कारण नोट आवश्यक करें
  • रिप्ले अनुमतियाँ सीमित भूमिका तक रखें
  • रिप्ले को पहले प्रयास जैसा ही idempotency चेक करवाएँ
  • रीप्ले पर रेट-लिमिट लगाएँ ताकि इन्सिडेंट के दौरान नया स्पाइक न बने
  • वैकल्पिक ड्राई-रन मोड जो वेरिफ़ाई करे बिना चेंज लिखे

इन्सिडेंट्स अक्सर एक से अधिक ईवेंट्स में होते हैं, इसलिए समय सीमा द्वारा रिप्ले का समर्थन करें (उदाहरण: "10:05 और 10:40 के बीच सभी फेल्ड ईवेंट्स रिप्ले करें")। लॉग करें कि किसने क्या, कब और क्यों रिप्ले किया।

आउटबाउंड वेबहुक: एक सेंडर फ्लो जिसे आप ऑडिट कर सकें

एक पूर्वानुमेय सेंडर बनाएं
स्थिर इवेंट IDs, प्रति-एंडपॉइंट ट्रैकिंग और रीट्राइ के साथ आउटबाउंड वेबहुक भेजें।
ऐप बनाएं

आउटबाउंड वेबहुक सामान्यतः बोरिंग कारणों से फेल होते हैं: रिसीवर धीमा है, अस्थायी आउटेज, DNS हिचकी, या प्रॉक्सी जो लंबी रिक्वेस्ट्स ड्रॉप कर दे। विश्वसनीयता आती है हर भेजे हुए ईवेंट को एक ट्रैक्ड, दोहराने योग्य जॉब मानकर—न कि एक वन-ऑफ HTTP कॉल।

एक सेंडर फ्लो जो प्रेडिक्टेबल रहे

हर ईवेंट को एक स्थिर, यूनिक इवेंट ID दें। यह ID रीट्राइज़, रिप्ले, और सर्विस रिस्टार्ट्स में समान रहना चाहिए। अगर आप हर प्रयास पर नया ID जनरेट करेंगे, तो रिसीवर के लिए डिडुपे मुश्किल होगा और आपके लिए ऑडिटिंग मुश्किल।

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

डिलिवरीज़ को एंडपॉइंट स्तर पर ट्रैक करें, केवल ईवेंट स्तर पर नहीं। अगर आप एक ही ईवेंट को तीन ग्राहकों को भेजते हैं, तो हर डेस्टिनेशन के पास अपनी कोशिशों का इतिहास और अंतिम स्टेटस होना चाहिए।

एक व्यावहारिक फ्लो जो अधिकांश टीमें लागू कर सकती हैं:

  • इवेंट रिकॉर्ड बनाएं: event ID, endpoint ID, payload hash, और प्रारंभिक स्टेटस
  • रिक्वेस्ट भेजें सिग्नेचर, टाइमस्टैम्प, और एक idempotency की हेडर के साथ
  • हर प्रयास रिकॉर्ड करें (start time, end time, HTTP status, संक्षिप्त एरर मैसेज)
  • केवल टाइमआउट्स और 5xx रिस्पॉन्स पर रीट्राइ करें, exponential backoff और jitter का उपयोग करते हुए
  • एक स्पष्ट सीमा के बाद रोक दें (मैक्स प्रयास या मैक्स आयु), फिर इसे समीक्षा के लिए फेल्ड मार्क करें

यह idempotency की हेडर तब भी महत्वपूर्ण है जब आप सेंडर हों। यह रिसीवर को एक साफ़ तरीका देता है डुप्लिकेट्स को हटाने का अगर उन्होंने पहले रिक्वेस्ट प्रोसेस किया पर आपका क्लाइंट 200 नहीं मिला।

अंत में, फेलियर्स को दृश्य बनाइए। "Failed" का अर्थ "खो गया" नहीं होना चाहिए। इसका मतलब होना चाहिए "पॉज़्ड, पर्याप्त संदर्भ के साथ ताकि सुरक्षित रूप से रिप्ले किया जा सके"।

उदाहरण: एक अस्थिर पार्टनर सिस्टम और साफ़ रिकवरी

आपका सपोर्ट ऐप टिकट अपडेट्स पार्टनर सिस्टम को भेजता है ताकि उनके एजेंट्स भी वही स्टेटस देखें। हर बार टिकट बदलता है (assignee बदलना, priority अपडेट, closed), आप ticket.updated जैसा वेबहुक पोस्ट करते हैं।

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

अब मुश्किल भाग: अगर आप idempotency का उपयोग नहीं करते, तो पार्टनर डुप्लिकेट्स प्रोसेस कर सकता है। प्रयास #1 हो सकता है कि उन्हें पहुँच चुकी हो, पर उनकी प्रतिक्रिया वापस नहीं आई। प्रयास #2 बाद में आकर दूसरा "Ticket closed" एक्शन बना देता है, दो ईमेल भेजता है या दो टाइमलाइन एंट्रीज़ बनाता है।

Idempotency के साथ, हर डिलीवरी में उसी ईवेंट से निकली idempotency की होती है (अक्सर बस event ID)। पार्टनर उस की को एक अवधि के लिए स्टोर कर लेते हैं और रिपीट्स के लिए "पहले से प्रोसेस्ड" जवाब देते हैं। आप अनुमान लगाना बंद कर देते हैं।

जब पार्टनर ठीक हो जाता है, रिप्ले वह तरीका है जिससे आप सच में गायब हुआ अपडेट (उदाहरण के लिए आउटेज के दौरान हुई priority change) वापस ठीक कर सकते हैं। आप अपने ऑडिट लॉग से ईवेंट चुनते हैं और उसे वही पेलोड और वही idempotency की के साथ एक बार फिर चलाते हैं, इसलिए यह सुरक्षित है भले ही उन्हें पहले ही मिल चुका हो।

इन्सिडेंट के दौरान, आपके लॉग्स को कहानी स्पष्ट बनानी चाहिए:

  • Event ID, ticket ID, event type, और payload version
  • प्रयत्न संख्या, टाइमस्टैम्प, और अगला रीट्राइ समय
  • टाइमआउट बनाम non-2xx रिस्पॉन्स बनाम सफलता
  • भेजा गया idempotency की, और क्या पार्टनर ने "duplicate" रिपोर्ट किया
  • किसने रिप्ले किया और अंतिम परिणाम क्या रहा—इसका रिकॉर्ड

आम गलतियाँ और जाल जिनसे बचें

ईवेंट डेटा को साफ़-सुथरा मॉडल करें
Webhook तालिकाओं को PostgreSQL में मॉडल करें और पार्टनर्स बदलने पर स्कीमा को स्थिर रखें।
अब शुरू करें

अधिकांश वेबहुक इन्सिडेंट्स एक बड़े बग से नहीं होते। वे छोटी-छोटी पसंदों से आते हैं जो ट्रैफ़िक बढ़ने या किसी थर्ड-पार्टी के flaky होने पर भरोसेमंदी तोड़ देती हैं।

पोस्टमोर्टम में दिखने वाले जाल:

  • रिक्वेस्ट हैंडलर के अंदर धीरा काम करना (डेटाबेस लिखना, API कॉल्स, फ़ाइल अपलोड) जब तक भेजने वाला टाइमआउट हो और रीट्राइ करे
  • मान लेना कि प्रोवाइडर्स कभी डुप्लिकेट नहीं भेजते, और फिर डबल-चार्ज, डबल-क्रिएट या दो ईमेल भेजना
  • गलत स्टेटस कोड लौटाना (200 लौटाना भले ही आपने ईवेंट स्वीकार न किया हो, या खराब डेटा के लिए 500 लौटाना जो रीट्राइ पर कभी सफल नहीं होगा)
  • कॉरिलेशन ID, ईवेंट ID, या रिक्वेस्ट ID के बिना शिप करना, और फिर घंटों लॉग मैच करने में बिताना
  • अनंत काल तक रीट्राइ करना, जो बैकलॉग बनाता है और पार्टनर आउटेज को आपके अपने आउटेज में बदल देता है

एक सरल नियम काम करता है: तेज़ स्वीकार करें, फिर सुरक्षित तरीके से प्रोसेस करें। केवल वह वैलिडेट करें जिसकी जरूरत है यह तय करने के लिए कि ईवेंट स्वीकार करना है या नहीं, उसे स्टोर करें, और बाकी असिंक्रोनस करें।

स्टेटस कोड्स अपेक्षा से ज़्यादा मायने रखते हैं:

  • 2xx का उपयोग केवल तब करें जब आपने ईवेंट स्टोर (या कतारबद्ध) कर लिया हो और आप आश्वस्त हों कि वह हैंडल किया जाएगा।
  • 4xx का उपयोग invalid input या failed auth के लिए करें ताकि भेजने वाला रीट्राइ बंद कर दे।
  • 5xx केवल आपकी साइड की अस्थायी समस्याओं के लिए उपयोग करें।

एक रीट्राइ सीमा सेट करें। एक निश्चित विंडो (जैसे 24 घंटे) या कोशिशों की संख्या के बाद रोक दें, फिर ईवेंट को "needs review" चिन्हित करें ताकि मानव यह निर्णय ले सके कि क्या रिप्ले करना है।

त्वरित चेकलिस्ट और अगले कदम

वेबहुक विश्वसनीयता ज्यादातर दोहराने योग्य आदतों के बारे में है: जल्दी स्वीकार करें, सख्ती से डिडुपे करें, ध्यान से रीट्राइ करें, और एक रिप्ले पथ रखें।

इनबाउंड (रिसीवर) त्वरित चेक्स

  • रिक्वेस्ट को सुरक्षित रूप से स्टोर कर लेने के बाद तेज़ 2xx रिटर्न करें (धीरा काम असिंक्रोनस रखें)।
  • जो कुछ आप रिसीव करते हैं उसे प्रूव करने के लिए पर्याप्त स्टोर करें (और बाद में डिबग करे)।
  • एक idempotency की मांग करें (या प्रोवाइडर + event ID से derive करें) और इसे DB में लागू करें।
  • खराब सिग्नेचर या invalid स्कीमा के लिए 4xx और केवल असली सर्वर समस्याओं के लिए 5xx उपयोग करें।
  • प्रोसेसिंग स्टेटस (received, processed, failed) और आखिरी एरर मैसेज ट्रैक करें।

आउटबाउंड (सेंडर) त्वरित चेक्स

  • हर ईवेंट के लिए यूनिक event ID असाइन करें और इसे प्रयासों में स्थिर रखें।
  • हर रिक्वेस्ट को साइन करें और टाइमस्टैम्प शामिल करें।
  • एक रीट्राइ पॉलिसी परिभाषित करें (बैकऑफ, मैक्स प्रयास, और कब रोकना है) और उसे अपनाएँ।
  • प्रति-एंडपॉइंट स्टेट ट्रैक करें: आखिरी सफलता, आखिरी असफलता, लगातार असफलताएँ, अगला रीट्राइ टाइम।
  • सपोर्ट और ऑडिट के लिए हर प्रयास लॉग करें और पर्याप्त विवरण रखें।

ऑप्स के लिए, पहले से तय करें कि आप क्या रिप्ले करेंगे (एकल ईवेंट, समय-सीमा के अनुसार बैच, या दोनों), कौन कर सकता है, और आपका डेड-लैटर रिव्यू रूटीन क्या होगा।

अगर आप ये टुकड़े बिना पूरी तरह हैंड-वायर्ड सिस्टम के बनाना चाहते हैं, तो एक नो-कोड प्लेटफ़ॉर्म जैसे AppMaster (appmaster.io) व्यावहारिक विकल्प हो सकता है: आप PostgreSQL में वेबहुक इनबॉक्स/आउटबॉक्स तालिकाएँ मॉडल कर सकते हैं, Business Process Editor में रीट्राइ और रिप्ले फ्लो लागू कर सकते हैं, और सपोर्ट के लिए एक अंदरूनी एडमिन पैनल शिप कर सकते हैं—बिना पूरा सिस्टम हाथ से कोड लिखे।

सामान्य प्रश्न

डेमो में वेबहुक भरोसेमंद क्यों दिखते हैं पर असल परियोजनाओं में टूटते हैं?

वेबहुक उन सिस्टमों के बीच होते हैं जिन्हें आप नियंत्रित नहीं करते, इसलिए आप उनके टाइमआउट, आउटेज, रीट्राइ और स्कीमा परिवर्तनों को विरासत में पाते हैं। भले ही आपका कोड सही हो, तब भी आप डुप्लिकेट, गायब ईवेंट, देरी और आर्डर से बाहर डिलीवरी देख सकते हैं।

इनबाउंड वेबहुक को भरोसेमंद बनाने का सबसे सरल तरीका क्या है?

शुरू से ही रीट्राइ और डुप्लिकेट को ध्यान में रखकर डिज़ाइन करें। हर इनकमिंग ईवेंट को स्टोर करें, इसे सुरक्षित रूप से रिकॉर्ड करने के बाद तेज़ 2xx से जवाब दें, और एक idempotency की के साथ असिंक्रोनस रूप से प्रोसेस करें ताकि दोहरे डिलीवरी से साइड-इफेक्ट्स दोहराए न जाएँ।

मेरा वेबहुक एंडपॉइंट कितना जल्दी रिस्पॉन्ड करना चाहिए?

बुनियादी वैलिडेशन और स्टोरेज के बाद जल्द से जल्द acknowledgement दें—आमतौर पर एक सेकंड से कम में। यदि आप रिक्वेस्ट के अंदर धीरा काम करते हैं तो भेजने वाला टाइमआउट लेगा और रीट्राइ बढ़ेंगे, जिससे डुप्लिकेट और जटिलताएँ बढ़ती हैं।

साधारण शब्दों में वेबहुक के लिए आइडेम्पोटेंसी का क्या मतलब है?

आइडेम्पोटेंसी का मतलब है “बिजनेस एक्शन को एक बार ही लागू करो, भले ही मैसेज कई बार आये।” इसे लागू करने के लिए स्थिर idempotency की (अक्सर प्रोवाइडर का ईवेंट ID) का उपयोग करें, उसे स्टोर करें और डुप्लीकेट के लिए सफलता रिटर्न करें बिना एक्शन दोहराए।

अगर प्रोवाइडर ईवेंट ID नहीं देता तो मैं क्या उपयोग करूँ?

अगर प्रोवाइडर ईवेंट ID देता है तो वही उपयोग करें। नहीं तो भरोसेमंद स्थिर फ़ील्ड्स से की निकाले—उदाहरण के लिए provider name + event type + resource ID + timestamp का हैश। बदलती फ़ील्ड्स पर निर्भर न करें; अगर स्थिर की नहीं बना पाएँ तो ईवेंट को क्वारंटीन करें बजाय अनुमान लगाने के।

रीट्राइ का सही व्यवहार सुनिश्चित करने के लिए किन HTTP स्टेटस को रिटर्न करना चाहिए?

जो समस्याएँ भेजने वाला खुद ठीक कर सके, उन पर रीट्राइ न करें। 4xx उन स्थितियों के लिए भेजें जिन्हें रीट्राइ से सुधारना नहीं है (जैसे failed auth या malformed payload)। 5xx केवल आपके अस्थायी समस्याओं के लिए इस्तेमाल करें। स्टेटस कोड पर सुसंगत रहें, क्योंकि वही अक्सर नियंत्रित करते हैं कि भेजने वाला रीट्राइ करेगा या नहीं।

रीट्राइ और रिप्ले में क्या अंतर है?

रीट्राइ स्वचालित और तुरंत किए जाते हैं; रिप्ले जानबूझकर पिछले ईवेंट्स को फिर से प्रोसेस करना है—जब आप बग फिक्स कर लें या आउटेज से रिकवर कर चुके हों। रिप्ले के लिए ईवेंट लॉग, सुरक्षित idempotency चेक और गार्डरेल्स चाहिए ताकि आप अनजाने में डुप्लिकेट काम न कर दें।

जैसे “closed” पहले आ जाये और “opened” बाद में—आउट-ऑफ-ऑर्डर ईवेंट्स कैसे संभालें?

आउट-ऑफ-ऑर्डर ईवेंट्स मान लें और अपने डोमेन के अनुसार एक नियम तय करें। एक आम तरीका है कि आप केवल तभी अपडेट लागू करें जब event version या timestamp हमारे पास मौजूद से नया हो—ताकि लेट आने वाले ईवेंट्स वर्तमान स्थिति को ओवरराइट न कर दें।

बिल्ड किए बिना ऑडिट ट्रेल और रिप्ले टूल कैसे लागू करूँ?

एक साधारण webhook inbox/outbox तालिका बनाएं और एक छोटा एडमिन व्यू—जहाँ आप फेल्ड ईवेंट्स को खोज, निरीक्षण और रिप्ले कर सकें। AppMaster (appmaster.io) में आप इन्हें PostgreSQL में मॉडल कर सकते हैं, dedupe, retry और replay फ्लो Business Process Editor में बना सकते हैं, और सपोर्ट के लिए इंटरनल पैनल बिना हैन्ड-कोडिंग के शिप कर सकते हैं।

शुरू करना आसान
कुछ बनाएं अद्भुत

फ्री प्लान के साथ ऐपमास्टर के साथ प्रयोग करें।
जब आप तैयार होंगे तब आप उचित सदस्यता चुन सकते हैं।

शुरू हो जाओ