طوابير الرسائل
طوابير الرسائل
طابور الرسائل هو حاجز مؤقت متين ومرتّب يجلس بين المكوّن الذي يُولّد العمل (المُنتِج Producer) والمكوّن الذي ينفّذه (المُستهلِك Consumer). بدلاً من أن يستدعي كل منهما الآخر مباشرة، يتواصلان عبر الطابور — يُسقط المُنتِج رسالة فيه ويمضي في طريقه، ثم يسحبها المُستهلِك متى كان جاهزاً. هذه الفكرة الواحدة تفتح آفاقاً واسعة في تصميم الأنظمة.
نموذج المُنتِج / المُستهلِك
كل نظام قائم على الطوابير يتكوّن من ثلاثة عناصر متحركة:
- المُنتِج (Producer) — يُنشئ رسالة ويُرسلها إلى طابور معيّن. تمثّل الرسالة وحدة عمل: طلب لمعالجته، صورة لتحجيمها، بريد إلكتروني لإرساله.
- الطابور (الوسيط Broker) — يُخزّن الرسالة بشكل متين حتى يتم تسليمها. الوسيط هو الوسيط بين الطرفين؛ يقبل الرسائل من المُنتِجين ويسلّمها للمُستهلِكين. من أبرز الوسطاء:
RabbitMQ، وAmazon SQS، وAzure Service Bus، وActiveMQ. - المُستهلِك (Consumer) — يستقصي الرسائل من الطابور أو يستقبلها ويعالجها. بعد المعالجة الناجحة يُرسل إشعار استلام (ack) للوسيط لحذف الرسالة نهائياً.
دلالات الطابور (Queue Semantics)
فهم السلوك الدقيق للطابور أمر بالغ الأهمية عند التصميم للدقة والصحة على نطاق واسع. أربعة خصائص رئيسية يجب معرفتها:
1. الترتيب
تُوفّر معظم الطوابير ترتيب FIFO (الأول دخولاً أول خروجاً) داخل طابور واحد أو قسم واحد. تُسلَّم الرسائل للمُستهلِكين بنفس ترتيب إدراجها في الطابور. غير أنه عند إضافة مُستهلِكين متعددين لزيادة الإنتاجية، يصعب الحفاظ على ترتيب عالمي صارم — إذ يسحب كل مُستهلِك الرسائل بشكل مستقل، فقد تعالج رسائل بترتيب مختلف عن الأصل. إن كان الترتيب الصارم ضرورياً (كتغييرات حالة حساب مستخدم)، فيجب إما استخدام مُستهلِك واحد، أو تقسيم الرسائل بمفتاح (مثل معرّف المستخدم) بحيث تذهب كل رسائل المستخدم نفسه إلى المُستهلِك ذاته.
2. مهلة الظهور (Visibility Timeout)
حين يستلم المُستهلِك رسالة، لا يحذفها الوسيط فوراً. بدلاً من ذلك، يُخفيها لمدة مهلة ظهور قابلة للضبط — لنقل 30 ثانية. إن أرسل المُستهلِك إشعار الاستلام خلال تلك المدة، حذف الوسيط الرسالة نهائياً. وإن انقضت المهلة دون إشعار (بسبب تعطّل المُستهلِك)، تعود الرسالة للظهور في الطابور وتُسلَّم لمُستهلِك آخر. هذه هي شبكة الأمان التي تمنع فقدان الرسائل عند تعطّل المُستهلِكين.
3. المتانة (Durability)
الطابور المتين يبقى سليماً عبر إعادة تشغيل الوسيط. تُكتب الرسائل على القرص (أو تُنسَّخ عبر العُقد) قبل أن يُرسل الوسيط إشعاراً للمُنتِج. هذا يضيف زمن تأخير — عادةً بضعة ميلي ثانية — لكنه غير قابل للتفاوض لأي شيء لا تستطيع تحمّل خسارته. يخزّن Amazon SQS الرسائل عبر مناطق توفر متعددة تلقائياً. أما RabbitMQ فيتطلب منك الإعلان عن الطابور ورسائله صراحةً بصفة durable وpersistent.
4. المُستهلِكون المتنافسون (Competing Consumers)
نمط تشغيل نسخ متعددة من المُستهلِكين على نفس الطابور يُسمى المُستهلِكون المتنافسون. وهو الطريقة الأساسية لتوسيع الإنتاجية: أضف المزيد من العمليات المُستهلِكة وكل واحدة تسحب الرسائل بشكل مستقل. إن كان لديك 10,000 رسالة في الطابور وشغّلت 20 عاملاً مُستهلِكاً، ستتوسع الإنتاجية بشكل شبه خطي — معالجة المتراكم أسرع بنحو 20 ضعفاً. الخدمات السحابية تجعل هذا بسيطاً: يمكن لـ Auto Scaling مراقبة عمق الطابور وإضافة نسخ EC2 أو استدعاءات Lambda تلقائياً.
أرقام حقيقية ومقايضات
لجعل قرارات التصميم ملموسة، إليك خصائص تمثيلية لأنظمة شائعة:
- Amazon SQS Standard: إنتاجية شبه غير محدودة، التسليم مرة واحدة على الأقل، أفضل ترتيب ممكن. الحجم الأقصى للرسالة 256 كيلوبايت. مهلة الظهور تصل إلى 12 ساعة. الاحتفاظ بالرسائل حتى 14 يوماً.
- Amazon SQS FIFO: ترتيب صارم ومعالجة مرة واحدة بالضبط داخل مجموعة الرسائل. الحد الأقصى 3,000 رسالة/ثانية مع الدُّفعات (300 بدونها). استخدمه حين يكون الترتيب ضرورياً مقابل قبول حد الإنتاجية.
- RabbitMQ: عُقدة وسيط واحدة تتحمّل نحو 50,000–100,000 رسالة/ثانية للرسائل الصغيرة. يدعم التوجيه المعقد (مباشر، بث، موضوع، رؤوس)، طوابير الأولوية، TTL، وتبادلات الرسائل الميتة بشكل طبيعي.
202 Accepted فوراً. هذا يُبقي زمن استجابة API منخفضاً ويجعل العمال قابلين للتوسع بشكل مستقل.
متى يكون الطابور الأداة الخاطئة
الطوابير قوية لكنها ليست عالمية. تجنّبها حين:
- يحتاج المُستدعي إجابة متزامنة. المستخدم الذي ينقر "إتمام الشراء" يحتاج أن يعلم الآن ما إذا نجحت الدفعة. يُدخل الطابور تأخيراً وتعقيداً في الحالة (تحتاج استطلاع للنتيجة أو WebSockets للاستجابة).
- تحتاج نشراً لمُشتركين مستقلين كثيرين. الطابور نقطة-إلى-نقطة يُسلّم كل رسالة لـمُستهلِك واحد فقط. لبث نفس الحدث لخدمات متعددة، استخدم موضوع pub/sub بدلاً من ذلك — وهو موضوع الدرس التالي.
- كان ترتيب الرسائل عبر الأقسام حرجاً وغير قابل للتفاوض. الطوابير القياسية لا تضمنه. فكّر في موضوع Kafka أحادي القسم أو طابور وظائف مدعوم بقاعدة بيانات.
الطابور هو أحد أقوى الأدوات الأساسية في تصميم الأنظمة الموزعة. إتقان متى وكيف تستخدمه — وما هي أوضاع فشله — سيُجني ثماره في كل تصميم على نطاق واسع تتصدّاه.