قوائم انتظار المهام مع Redis
قوائم انتظار المهام مع 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);أحداث المهام والمراقبة
استمع إلى أحداث المهام للمراقبة والتسجيل ومعالجة الأخطاء.
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());منطق إعادة المحاولة
قم بتكوين إعادة المحاولة التلقائية للمهام الفاشلة مع تأخير أسي متزايد.
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');