من Hangfire إلى RabbitMQ: التخلص من استطلاع قاعدة البيانات (Polling)

Hangfire خيار رائع للفرق الصغيرة. كل ما عليك فعله هو إضافة حزمة NuGet وتوجيهها إلى قاعدة البيانات الخاصة بك. ستحصل على مشغل مهام (job runner) ولوحة تحكم (dashboard) مجانًا. بالنسبة لخدمة واحدة، من الصعب التفوق عليه.

استخدمت Hangfire في SavePosty للتعامل مع رسائل البريد الإلكتروني، وwebhooks، وجلب المحتوى. كانت كل مهمة تعمل بنفس الطريقة؛ حيث كانت جميعها تقوم بعملية استطلاع (polling) لقاعدة بيانات Postgres الخاصة بي كل بضع ثوانٍ للتحقق من وجود مهام جديدة.

في النهاية، نقلت كل شيء إلى RabbitMQ. إليكم سبب قيامي بذلك وما فقدته.

لماذا انتقلت:

  • عبء الاستطلاع (Polling load) يتزايد مع الوقت، وليس مع حجم العمل. كل مهمة في Hangfire تضغط على قاعدة البيانات الخاصة بك بناءً على مؤقت زمني. حتى لو لم يكن هناك عمل، تظل قاعدة البيانات مشغولة. وتزداد هذه التكلفة مع زيادة عدد المهام وتكرار الاستطلاع.
  • كثرة النماذج (Models). كان جزء من تطبيقي يستخدم RabbitMQ بالفعل، بينما استخدم الجزء المتبقي Hangfire. كان هذا يعني وجود طريقتين مختلفتين لإدارة العمل في الخلفية. الانتقال إلى RabbitMQ وحد كل شيء.
  • زمن الاستجابة (Latency). يقوم الوسيط (broker) بدفع العمل فور وصوله، بينما ينتظر Hangfire موعد الاستطلاع التالي.

المقايضات:

Hangfire سهل الإعداد. يستخدم جداول SQL الموجودة لديك، ويحتوي على لوحة تحكم مدمجة رائعة.

يتطلب RabbitMQ إدارة وسيط (broker). هو يستخدم ذاكرة الوصول العشوائي (RAM) والشبكة بدلاً من وحدة المعالجة المركزية (CPU) لقاعدة البيانات. ستحصل على توسع (scaling) أفضل، ولكن مع عبء تشغيلي أكبر.

كيف قمت بالهجرة بأمان:

حافظت على منطق العمل (business logic) كما هو تمامًا. قمت ببناء مستهلكين (consumers) خفيفين يعملون كبوابة أمامية. يستلم المستهلك الرسالة ويسلمها إلى فئة المهمة (job class) الموجودة مسبقًا.

ركزت على شيئين:

  • تكافؤ إعادة المحاولة (Retry parity). قمت بمطابقة إعدادات إعادة المحاولة في Hangfire مع مستهلك RabbitMQ حتى لا أفقد أي رسائل.
  • سلامة المخطط (Schema safety). أبقيت الأعمدة القديمة قابلة للقيمة الفارغة (nullable) حتى لا أتسبب في تعطل قاعدة البيانات أثناء عملية النشر (deploy).

ما فقدته:

العيب الأكبر هو الرؤية (visibility). يتيح لك Hangfire النقر على مهمة فاشلة ورؤية ما حدث بالضبط. يوضح لك RabbitMQ عدد الرسائل الموجودة في طابور الرسائل الميتة (Dead Letter Queue)، لكنه لا يمنحك نفس العرض السهل لكل مهمة على حدة. أنا الآن أعتمد على السجلات المهيكلة (structured logs) بدلاً من لوحة التحكم.

نصيحتي:

ابقَ على Hangfire إذا:

  • كنت تدير خدمة واحدة.
  • كان لديك فريق صغير.
  • كنت بحاجة إلى لوحة تحكم سهلة لتصحيح الأخطاء (debugging).

انتقل إلى RabbitMQ إذا:

  • كان لديك خدمات متعددة.
  • كان عبء الاستطلاع على قاعدة البيانات مرتفعًا.
  • كنت تريد استخدام أنماط pub/sub.

يعتمد القرار على نظامك، وليس على مهمة واحدة فقط.

المصدر: https://dev.to/gabrielleroux/from-hangfire-to-rabbitmq-killing-database-polling-in-a-net-app-4og4

مجتمع تعليمي اختياري: https://t.me/GyaanSetuAi