تزداد تعقيد الأنظمة البرمجية الحديثة وتوزيعها، وتُطلب منها الاستجابة السريعة. غالباً ما تواجه نماذج الطلب والاستجابة المتزامنة التقليدية صعوبة في تلبية هذه المتطلبات، مما يؤدي إلى خدمات مترابطة بشدة ومختنقات. هنا تأتي البنية الموجهة بالأحداث (EDA). من خلال فك ارتباط المنتجين والمستهلكين عبر الأحداث، تتيح EDA للأنظمة أن تكون أكثر قابلية للتوسع، ومرونة، وقدرة على التكيف. في هذا المنشور، سنغوص في المكونات الأساسية التي تشكل بيئة عمل قوية موجهة بالأحداث، بما في ذلك سعاة الرسائل، وتصحيح الأحداث، وفصل مسؤوليات الأوامر والاستعلامات (CQRS).
قوة فك الارتباط باستخدام سعاة الرسائل
في صميم أي نظام موجه بالأحداث يوجد سعاة الرسائل. يعمل كوسيط يقبل الرسائل ويخزنها ويوجهها بين المنتجين والمستهلكين. توفر سعاة الرسائل الشائعة مثل RabbitMQ وApache Kafka وAWS SQS ميزات أساسية مثل الاستمرارية، والمتانة، وقابلية التوسع. الفائدة الرئيسية هنا هي فك الارتباط؛ حيث لا تحتاج الخدمة إلى معرفة من أو ما الذي يستهلك أحداثها. هذا يسمح للفرق بنشر الخدمات بشكل مستقل وتوسيع أجزاء معينة من النظام بناءً على الحمل.
على سبيل المثال، ضع في اعتبارك خدمة طلبات التجارة الإلكترونية. عند تقديم طلب، تنشر حدث OrderCreated. يمكن لخدمات الدفع، والمخزون، والإشعارات الاشتراك في هذا الحدث دون حاجة خدمة الطلبات إلى معرفة وجودها.
تصحيح الأحداث: مصدر الحقيقة
تصحيح الأحداث (Event Sourcing) هو نمط تصميم يتم فيه تحديد حالة التطبيق من خلال تسلسل من الأحداث غير القابلة للتغيير بدلاً من الحالة الحالية فقط. بدلاً من حفظ النتيجة النهائية للتغيير فقط (كما هو الحال في عمليات CRUD التقليدية)، تقوم بحفظ كل تغيير كحدث.
يوفر هذا النهج عدة مزايا:
- إمكانية التدقيق: لديك سجل كامل لجميع التغييرات.
- التصحيح: يمكنك إعادة تشغيل الأحداث لإعادة إنتاج الأخطاء.
- الاستعلامات الزمنية: يمكنك إعادة بناء حالة النظام في أي نقطة زمنية.
يوضح المثال المفاهيمي المبسط أدناه في Java كيفية تخزين الأحداث واسترجاعها:
public class OrderAggregate {
private List events = new ArrayList<>();
public void placeOrder(Order order) {
events.add(new OrderCreatedEvent(order.getId(), order.getItems()));
saveEventsToStream(events);
}
public List getHistory() {
return Collections.unmodifiableList(events);
}
}
CQRS: فصل القراءة عن الكتابة
يكمل فصل مسؤوليات الأوامر والاستعلامات (CQRS) تصحيح الأحداث من خلال فصل العمليات التي تقرأ البيانات (الاستعلامات) عن تلك التي تعدل البيانات (الأوامر). في البنية التقليدية، يتم استخدام نموذج قاعدة بيانات واحد لكل من الاثنين. في CQRS، يمكنك تحسين نموذج القراءة للاستعلام السريع (على سبيل المثال، باستخدام Elasticsearch) مع الحفاظ على نموذج الكتابة محسناً للاتساق والتزامن.
هذا الفصل حاسم في الأنظمة عالية الإنتاجية حيث تختلف أنماط القراءة بشكل كبير عن أنماط الكتابة. على سبيل المثال، قد يكون لديك ملايين القراءات في الثانية لعروض المنتجات ولكن مئات فقط من الكتابات لتحديثات المخزون. يسمح لك CQRS بتوسيع هذه العمليات بشكل مستقل.
بناء سير العمل التفاعلي
تركز البنى التفاعلية على السلوك غير الحاجز وغير المتزامن. من خلال الجمع بين الأحداث، وسير العمل غير المتزامن، وتدفقات الاستجابة، يمكن للأنظمة التعامل مع التزامن العالي باستخدام موارد أقل. تسمح أطر العمل مثل Akka أو Project Reactor للمطورين بتركيب خطوط أنابيب غير متزامنة تتفاعل مع التغييرات في الوقت الفعلي.
عند دمج هذه الأنماط، من الضروري التعامل مع الأعطال بلطف. تعد قابلية التكرار (Idempotency) أمراً أساسياً؛ يجب أن يكون المستهلكون قادرين على معالجة الحدث نفسه عدة مرات دون التسبب في تلف البيانات. يتحقق ذلك غالباً باستخدام معرفات أحداث فريدة وتتبعها في متجر خاص بالمستهلك.
الخاتمة
توفر البنية الموجهة بالأحداث، عند دمجها مع تصحيح الأحداث وCQRS، مجموعة أدوات قوية لبناء أنظمة حديثة وقابلة للتوسع ومرنة. وعلى الرغم من أن التعقيد يزداد مقارنة بالتصاميم أحادية الكتلة التقليدية، فإن الفوائد من حيث المرونة والأداء وقابلية الصيانة كبيرة. بالنسبة للمطورين من المستوى المتوسط إلى المتقدم، يعد إتقان هذه الأنماط أمراً أساسياً للتنقل في تحديات الحوسبة الموزعة في المشهد الحديث المعتمد على السحابة.