المستوى المطلوب: متوسط — يفترض إنك تعرف Node.js وتعاملت مع Express قبل كده، ومش شرط تكون استعملت Redis قبلًا.
لو تطبيقك بيبعت 50 ألف webhook شهريًا لعملاء الـ API بتاعك، و4% منهم بيضيع لما الـ subscriber يقع لحظتين، انت بتفقد ثقة العملاء على مشكلة بتتحل في 90 سطر كود. أي حل بدون retry queue هيخسّرك بين 1,800 و 2,000 webhook كل شهر، والعميل اللي ميستلمش الإشعار بيفتح ticket الصبح.
Webhook Delivery System موثوق على Node.js و BullMQ
المشكلة باختصار
الـ webhook في ظاهره طلب POST بسيط لـ URL العميل. لكن لما العميل يكون عنده deploy جديد، أو شبكته بتعاني timeout، أو السيرفر بتاعه رد بـ 503 لمدة 4 ثوان — الطلب بتاعك بيضيع. أسلوب "fire and forget" مع fetch() مباشرة معناه إن webhook فاشل واحد بيتمسح من الذاكرة في millisecond، والعميل يعرف بالخطأ بعد يومين لما يفتح الـ dashboard ويلاقي بيانات ناقصة.
مثال للمبتدئ: ساعي البريد المُصرّ
تخيّل ساعي بريد يمرّ على بيت العميل ويلاقي الباب مقفول. في النموذج الأول بيرمي الجواب في الزبالة ويمشي. في النموذج التاني بيكتب ملاحظة "هرجع بعد ساعة"، يحطّه في درج البريد، وبكرة الصبح يحاول تاني، وبعدها بعد 4 ساعات. لو 12 محاولة فشلت، يبعت SMS للعميل: "ادّينا 12 ساعة وما لقينا حد، تعالى خد الجواب من المكتب". BullMQ بيعمل دور ساعي البريد التاني بالظبط: بيخزّن المحاولات في Redis، يعيدها على فترات متباعدة، وبعد سقف محدد يرميها في dead letter queue للمراجعة اليدوية.
التعريف العلمي للـ Exponential Backoff
الـ Exponential Backoff خوارزمية موثّقة من ورقة Karn و Partridge في مجلة ACM Transactions on Computer Systems سنة 1991 ضمن TCP retransmission strategy. الفكرة بسيطة: زمن انتظار المحاولة رقم n يساوي base × 2^n مع jitter عشوائي. ده بيمنع ظاهرة "الـ thundering herd" لما 5,000 client يفشلوا في نفس الثانية ويعيدوا كلهم بعد دقيقة بالظبط، فيوقّعوا السيرفر تاني. مع jitter ±15% المحاولات بتتوزّع على مدى 12 دقيقة بدل دقيقة واحدة.
الحل التنفيذي: BullMQ + Redis في 90 سطر
BullMQ مكتبة Node.js مبنية على Redis Streams، بتدير طوابير معالجة فيها:
- Persistence على القرص: لو السيرفر اتعاد، الجوبز محفوظة.
- Retry strategies جاهزة (exponential, fixed, linear).
- Concurrency control: شغّل 50 worker متزامن بدون ما تخنق Redis.
- Observability: dashboard جاهز عبر
bull-board.
الكود التالي يفترض إن عندك Redis 7+ شغّال على localhost:6379 و Node.js 22:
npm install bullmq ioredis axios