
نمط النشر-الاشتراك (Pub/Sub)
دعونا نواجه الأمر. لا ينبغي للعميل أن ينتظر حتى ينتهي كل المعالجة في (backend).
تخيل أنك تقوم بتحميل فيديو على يوتيوب. هل يجب على العميل حقًا أن يجلس وينتظر بينما يقوم يوتيوب بمعالجة الفيديو، وترميزه، وفحصه بحثًا عن حقوق النشر (copyright)، ثم إرسال الإشعارات؟ بالتأكيد لا.
🧠 لماذا Pub/Sub؟
تتكون العديد من الأنظمة الحديثة من خدمات مستقلة تعمل معًا.
على سبيل المثال: UploadService → ParseService → CopyrightService → NotificationService.
إذا كانت هذه الخدمات تتصل ببعضها البعض مباشرةً وبشكل متسلسل، فإن النظام يصبح شديد الترابط (tightly coupled) ويصعب صيانته أو التعافي من الأعطال.
إذا فشلت إحدى الخدمات، فقد تنكسر السلسلة بأكملها.
هذا النهج لا يتوسع بشكل جيد (doesn't scale well).
هنا يأتي دور نمط النشر-الاشتراك (Publish–Subscribe).
📦 كيف يعمل Pub/Sub؟
يقوم العميل بتحميل ملف (مثل فيديو أو ملف PDF).
يستجيب الخادم بحالة نجاح ويمكن للعميل قطع الاتصال.
يقوم UploadService بعد ذلك بنشر حدث (event) إلى موضوع (topic) (مثل "upload.video").
يقوم وسيط الرسائل (message broker) (مثل Kafka, RabbitMQ, إلخ) بإبلاغ جميع المشتركين (subscribers) المهتمين بهذا الموضوع.
يؤدي كل مشترك (subscriber) مهمته (التحليل، الفحص، إنشاء الصور المصغرة، إرسال الإشعارات...) وقد يقوم بنشر أحداث أخرى إلى مواضيع أخرى.
يصبح كل شيء غير مترابط (decoupled)، وقابلاً للتوسع (scalable)، وأسهل بكثير في الصيانة.
🧪 مثال من واقع الخبرة
لقد عملت على مشروع يقوم فيه المستخدمون بتحميل ملفات PDF.
إليك ما حدث بعد التحميل:
يقوم الخادم بتحويل ملف PDF إلى نص ويخزنه في قاعدة البيانات.
تقوم خدمة ثانية بإنشاء صورتين (صورة مصغرة ومعاينة عالية الدقة) من الصفحة الأولى.
تم تحميل كل من ملف PDF والصور إلى Azure Blob Storage.
فقط بعد تحميل ملف PDF، تلقى العميل استجابة نجاح (success response) وقام بقطع الاتصال.
إذا كنا قد طبقنا نمط Pub/Sub، لكان العميل قد انتظر فقط تحميل ملف PDF. كل شيء آخر مثل المعالجة والتحويل وتحميل الصور كان يمكن أن يحدث بشكل غير متزامن (asynchronously) في الخلفية، ويتم التعامل معه بواسطة خدمات منفصلة عبر مواضيع (topics) مشتركة.