Redis والتخزين المؤقت المتقدم

قوائم انتظار المهام مع Redis

18 دقيقة الدرس 16 من 30

قوائم انتظار المهام مع Redis

تسمح قوائم انتظار المهام بمعالجة المهام المستهلكة للوقت بشكل غير متزامن في الخلفية. يوفر Redis وظائف قائمة انتظار سريعة وموثوقة من خلال مكتبات مثل Bull.

ما هي قوائم انتظار المهام؟

تفصل قوائم انتظار المهام بين تنفيذ المهام ومعالجة الطلبات. بدلاً من جعل المستخدمين ينتظرون العمليات البطيئة (رسائل البريد الإلكتروني، معالجة الصور، التقارير)، تضيف المهام إلى قائمة انتظار وتعالجها في الخلفية.

الفوائد: تحسين أوقات الاستجابة، استخدام أفضل للموارد، منطق إعادة المحاولة، تحديد أولويات المهام، وقابلية التوسع.

مكتبة Bull Queue

Bull هي مكتبة قوائم انتظار المهام الأكثر شيوعًا في Node.js المبنية على Redis. توفر ميزات قوية لإدارة مهام الخلفية.

const Queue = require('bull');\n\n// إنشاء قائمة انتظار\nconst emailQueue = new Queue('email-queue', {\n  redis: {\n    host: '127.0.0.1',\n    port: 6379\n  }\n});\n\n// إضافة مهام إلى القائمة\nawait emailQueue.add({\n  to: 'user@example.com',\n  subject: 'مرحباً!',\n  body: 'شكراً لتسجيلك'\n});\n\nconsole.log('تمت إضافة المهمة إلى القائمة');

معالجة المهام

حدد معالجات لمعالجة المهام من القائمة. تعمل المعالجات في عمليات منفصلة ويمكن توسيعها بشكل مستقل.

// ملف المعالج: emailProcessor.js\nconst emailQueue = require('./emailQueue');\nconst nodemailer = require('nodemailer');\n\nemailQueue.process(async (job) => {\n  const { to, subject, body } = job.data;\n  \n  // إرسال البريد الإلكتروني\n  await transporter.sendMail({\n    from: 'noreply@app.com',\n    to,\n    subject,\n    text: body\n  });\n  \n  return { sent: true, to };\n});
نصيحة: شغّل المعالجات في عمليات أو حاويات منفصلة لقابلية توسع أفضل وعزل أكبر.

أولويات المهام

حدد أولويات للمهام للتحكم في ترتيب المعالجة. تتم معالجة المهام ذات الأولوية الأعلى أولاً.

// مهمة ذات أولوية عالية (رقم أقل = أولوية أعلى)\nawait emailQueue.add(\n  { to: 'admin@app.com', subject: 'تنبيه حرج' },\n  { priority: 1 }\n);\n\n// أولوية عادية\nawait emailQueue.add(\n  { to: 'user@app.com', subject: 'نشرة إخبارية' },\n  { priority: 5 }\n);\n\n// أولوية منخفضة\nawait emailQueue.add(\n  { to: 'user@app.com', subject: 'تسويق' },\n  { priority: 10 }\n);

المهام المتأخرة

جدولة المهام لتشغيلها بعد تأخير محدد أو في وقت محدد.

// تأخير المهمة بساعة واحدة (بالميلي ثانية)\nawait emailQueue.add(\n  { to: 'user@app.com', subject: 'تذكير' },\n  { delay: 60 * 60 * 1000 }\n);\n\n// جدولة لوقت محدد\nconst scheduledTime = new Date('2026-02-17T10:00:00Z');\nawait emailQueue.add(\n  { to: 'user@app.com', subject: 'بريد مجدول' },\n  { delay: scheduledTime.getTime() - Date.now() }\n);

المهام المتكررة

أنشئ مهام متكررة تعمل وفقًا لجدول زمني باستخدام أنماط cron.

// التشغيل كل يوم في منتصف الليل\nawait emailQueue.add(\n  { type: 'daily-report' },\n  {\n    repeat: {\n      cron: '0 0 * * *'\n    }\n  }\n);\n\n// التشغيل كل 15 دقيقة\nawait emailQueue.add(\n  { type: 'health-check' },\n  {\n    repeat: {\n      every: 15 * 60 * 1000\n    }\n  }\n);
أنماط Cron: استخدم بناء جملة cron القياسي - دقيقة، ساعة، يوم، شهر، يوم الأسبوع. '0 0 * * *' يعني منتصف الليل كل يوم.

أحداث المهام والمراقبة

استمع إلى أحداث المهام للمراقبة والتسجيل ومعالجة الأخطاء.

emailQueue.on('completed', (job, result) => {\n  console.log(`المهمة ${job.id} اكتملت:`, result);\n});\n\nemailQueue.on('failed', (job, err) => {\n  console.error(`المهمة ${job.id} فشلت:`, err);\n  // إرسال تنبيه أو منطق إعادة المحاولة\n});\n\nemailQueue.on('progress', (job, progress) => {\n  console.log(`تقدم المهمة ${job.id}: ${progress}%`);\n});

لوحة تحكم Bull Board

يوفر Bull Board واجهة ويب لمراقبة وإدارة قوائم الانتظار والمهام والعمال.

const { createBullBoard } = require('@bull-board/api');\nconst { BullAdapter } = require('@bull-board/api/bullAdapter');\nconst { ExpressAdapter } = require('@bull-board/express');\n\nconst serverAdapter = new ExpressAdapter();\nserverAdapter.setBasePath('/admin/queues');\n\ncreateBullBoard({\n  queues: [new BullAdapter(emailQueue)],\n  serverAdapter\n});\n\napp.use('/admin/queues', serverAdapter.getRouter());
نصيحة: احمِ Bull Board باستخدام middleware للمصادقة في بيئات الإنتاج.

منطق إعادة المحاولة

قم بتكوين إعادة المحاولة التلقائية للمهام الفاشلة مع تأخير أسي متزايد.

await emailQueue.add(\n  { to: 'user@app.com' },\n  {\n    attempts: 3,\n    backoff: {\n      type: 'exponential',\n      delay: 2000 // ابدأ بـ 2 ثانية\n    }\n  }\n);\n\n// دالة تأخير مخصصة\nawait emailQueue.add(\n  { to: 'user@app.com' },\n  {\n    attempts: 5,\n    backoff: (attemptsMade) => {\n      return Math.pow(2, attemptsMade) * 1000;\n    }\n  }\n);
تحذير: لا تحدد إعادة محاولات غير محدودة. حدد دائمًا عددًا أقصى من المحاولات لمنع حلقات إعادة المحاولة اللانهائية.

دورة حياة المهمة

فهم دورة الحياة الكاملة للمهمة يساعد في التصحيح والتحسين.

// حالات المهمة:\n// waiting - في القائمة، في انتظار المعالجة\n// active - قيد المعالجة حالياً\n// completed - انتهت بنجاح\n// failed - فشلت المعالجة\n// delayed - في انتظار انتهاء التأخير\n// paused - القائمة متوقفة مؤقتاً\n\n// الحصول على المهام حسب الحالة\nconst waiting = await emailQueue.getWaiting();\nconst active = await emailQueue.getActive();\nconst failed = await emailQueue.getFailed();\n\n// تنظيف المهام القديمة\nawait emailQueue.clean(24 * 3600 * 1000, 'completed');
تمرين: أنشئ قائمة انتظار لمهام معالجة الصور. أضف مهامًا بأولويات مختلفة (إنشاء صورة مصغرة = عالية، إضافة علامة مائية = منخفضة). نفّذ معالجًا يحاكي معالجة الصور بتأخيرات. أضف منطق إعادة المحاولة للفشل وراقب معدلات إكمال المهام.