المقدمة

في تطبيقات الويب الحديثة، تُعد أنظمة الإشعارات عنصرًا أساسيًا لتعزيز تفاعل المستخدمين. سواءً كنت تُنشئ منصة تواصل اجتماعي، أو تطبيق تجارة إلكترونية، أو نظام إدارة محتوى، فستحتاج إلى طريقة فعّالة لإرسال الإشعارات إلي المستخدمين.

في المقال ده هتكلم عن تصميم نظام إشعارات scalable بلغة Nodejs و هركز اكتر على: 

  1. Architectural Design (تصميم معمارية النظام بتاعنا)
  2. Database Choices (SQL vs NoSQL) (إختيار الداتا بيز الأمثل للنظام)
  3. Efficient Notification Processing 
  4. Horizontal Scaling Strategies

ما قبل إنشاء نظام إشعارات فعال

علشان تنشئ نظام فعال وناجح تعالى نتعرف على المتطلبات الأساسية:

  1. عاوزين نخلي السيستم بتاعنا multi-channel support بمعنى أنه يقدر يبعت إشعارات من أكتر من خدمة زي email أو من ال app بتاعنا أو SMS  وغيرها .
  2. عاوزين نظام الإشعارات يبقى في ال real time او حتى نعملها schedule بمعني تتبعت في وقت معين.
  3. عاوزين نضيف بيانات خاصة بالمستخدم في الإشعار علشان ده بيلفت انتباهه يحسسه انه ليه وده حاجه بنسميها Personalization.
  4. نعمل tracking للإشعارات بتاعتنا ونشوف هي وصلت واتفتحت ولا لا وهكذا .
  5. طبعا ال scalability علشان نضمن إنها تقدر توصل لكل مستخدمين السيستم اللي ممكن يعدوا ال 1M مستخدم.

طيب يلا نعمل Design لـ Scalable Architecture .


Building a Scalable Notification System

طيب الحاجات الأساسية عندنا للسيستم وهي: 

1- API endpoint: عاوزين نضمن إنه يقبل الطلبات من اي service .

المثال على النقطة الأولى ده: 

POST /api/notifications { userId, type, message, metadata }

2- نختار نوع ال Database اللي هنخزن فيها الإشعارات : 

  •  (Sql databases (postgreSQL : ده أفضل في الـ queries المعقدة
  •  (No sql database(MongoDB : افضل للإشعارات البسيطة.

3- هنعمل Message Queue للعمليات ال Asynchronous و هنا ممكن نستخدم Redis او RabbitMQ.

4- هنستخدم  ال Workers وده طبعا هتفيدنا إننا منعملش difficult jobs على ال main thread بتاعنا. 

5- أخر حاجه عندنا وهو إننا نحدد الـ third party library اللي هنستخدمها في الإشعارات زي: 

  1. Send grid : ده بنستخدمه علشان نبعت إشعارات ورسائل على الـ mail 
  2. Twilio : ده بيبعت رسايل SMS 
  3. FCM : طبعا ده ال Firebase cloud messaging وبنستخدمها لل push notifications 

تمام كده خلصنا ال Core components للسيستم بتاعنا ناقص بس نحدد ال flow بتاع السيستم او ازاي هو بيشتغل من الاول للاخر .

بكل بساطة علشان منعقدهاش هو العميل أو الكلاينت بيبعت request يروح لل api بتاعنا يتعمل queue وبعدها اكيد هتخش على ال Worker علشان نشغلها parallel للكود بتاعنا و بعدها تروح لل service بتاعنا الخارجية زي ال twilio وهكذا واخيرا هتروح لل database بتاعنا علشان تتخزن في السيستم عندنا.

[Client] → [API Server] → [Message Queue] → [Worker] → [External Services]

                     ↳ [Database (PostgreSQL/MongoDB)]


يلا بينا نبدأ نكتب الكود بتاعنا ب NodeJS

  1. اول حاجه نعمل ال Database Setup وهنستخدم mongoDB.
Database Setup
Database Setup

ال schema الخاصة ب notification model فيها type وده زي ما قولنا ممكن تبقي mail أو SMS أو push. و ال status ده ممكن تبقي ٣ أنواع بردو ( pending , failed , sent ).

  1. بعد ال Database بقى نكتب ال API بتاعنا و هنستخدم في الحالة ده express ك framework ل node js.
  2. وهنستخدم library جديدة متكلمتش عنها وهي bullmq وهي Redis-based library علشان تعمل عمليات في الـ background.
  3. طيب في الـ end point بتاعتنا هنستقبل ال userId أكيد اللي عاوزين نبعتله notification وال message و type بتاعها سواء mail أو غيرها.
  4. طبعا الكلام هنا هو على design ممكن تزود attributes انت شايفها مهمه او تشيل منها براحتك.
  5. بعد ما نخزن ال notification في mongoDB على أساس إنها pending طبعا ، هنضيف ال notification لل redis-queue بال reference بتاعها علشان ال tracking في ال DB.  
API With NodeJS
API With NodeJS

خلصنا ال queue بقا نروح نعمل ال worker اللي هي listen عليها علشان ينفذ العمليات بتاعتنا. طب ليه احنا مستخدمين ال architecture ده ؟ التصميم ده ليه ٣ مميزات: 

  1. نعمل Decoupling بحيث منوقفش عمل الـ api لحد ما الإشعار يتبعت.
  2. ال bullmq فيها mechanism إنها العمليات اللي فشلت بتعيدها تاني.
  3. وطبعا ال scalability بحيث أن اكتر من worker يقدروا يشتغلوا parallel مع بعض بدون التأثير علي main thread .

في شوية نقط تتقال علي الكود و منها إن إسم ال worker لازم يبقى زي إسم ال queue وإننا هنجيب ال notification عن طريق الـ id بتاعها زي ما عملنا في ال queue اللي كان جوه ال api.

Processing Notification With Bullmq
Processing Notification With Bullmq

مثال على ال mail وهنستخدم  send grid علشان نبعت mail notification لمستخدم ما عندنا على السيستم .

Send Email With SendGrid 
Send Email With SendGrid 

بتحط مكان ال from الإيميل بتاع الموقع بتاعك و ال to بتبعت لل function ال email بتاع المستخدم اللي هتجيبه من الداتا بيز .

بس كدا انت كده خدت فكرة إزاي تعمل notification سيستم كويس و scalable و تعمل design لل flow بتاع الداتا بتاعتك في ال app بطريقة تعلي من كفاءة الشغل بتاعك . 🎉


بعض النصائح الأخيرة لتطوير النظام.

  1. احنا في المثال معملناش ال schedule notification فممكن تضيفها عندك و فكرتها انك هتعمل cron job للي معمولها pending في وقت معين وتكون مخزنها في redis .
  2. بالنسبة لل Horizontal scaling ممكن تعمل multiple  workers علي اكتر من server وكمان ممكن تستخدم redis cluster لل queue الموزعة على اكتر من server.
  3. طبعا تضيف ال rate limiting  و تشوف استخدامات لل Retry mechanism بتاع ال bullmq .

في الختام

في الوقت الحالي نظام الإشعارات أساسي في أي نظام ويتضمن تصميم قوي وشغل كتير. ومستنيكم في المقالات الجايه إن شاء الله.