مستوى المقال: مبتدئ. محتاج تعرف تكتب دالة بسيطة في Node.js وتشغّل أمر في الترمنال. مش محتاج خبرة سابقة في الطوابير (Queues) ولا Redis — هنبدأ من الصفر بمثال واضح قبل أي كود.
اعمل Background Jobs بـ BullMQ و Redis في Node.js
لو زرار "سجّل" في موقعك بيبعت إيميل ترحيب وبياخد 4 ثواني قبل ما المستخدم يشوف أي رد، انت بتخلّي المستخدم يدفع تمن شغل مالوش دعوة يستناه. الحل إنك تفصل الشغل البطيء عن الـ request، وترجّع للمستخدم فورًا. ده اسمه Background Job، وهنبنيه دلوقتي خطوة بخطوة بـ BullMQ و Redis، وننزّل زمن استجابة الـ API من 4200 مللي ثانية لـ 80 مللي ثانية.
المشكلة باختصار
لما المستخدم يعمل أكشن (تسجيل، رفع صورة، طلب فاتورة)، فيه شغل تقيل وراه: إرسال إيميل، توليد PDF، تصغير صورة، نداء API بتاع طرف تالت. لو عملت الشغل ده جوّه نفس الـ request، المستخدم بيفضل مستني لحد ما كل حاجة تخلص. ولو الخدمة الخارجية (زي سيرفر الإيميل) بطيئة أو وقعت، الـ request بتاعك بيقع معاها.
الفكرة: بدل ما تعمل الشغل ده قدام المستخدم، انت بترميه في "طابور" (queue)، وترجّع رد سريع، وبعدين عامل في الخلفية (worker) بياخد الشغل من الطابور وينفّذه على راحته.
قبل الكود: مثال بسيط جداً
تخيّل مطعم وجبات سريعة. لو الكاشير هو اللي يطبخ كل طلب بإيده قبل ما يستقبل العميل اللي بعده، الطابور هيوصل للشارع. اللي بيحصل فعلاً في أي مطعم محترم: الكاشير بياخد الطلب، يكتبه على ورقة، يعلّقها في المطبخ، وفورًا يقول للعميل "تمام، رقمك 47". المطبخ (الطباخ) بيسحب الورق ويطبخ بالترتيب.
هنا الكاشير = الـ API بتاعك. الورقة المعلّقة = المهمة (job) في الطابور. المطبخ = الـ worker. العميل مش بيستنى الأكل يتطبخ عشان ياخد رقمه.
دلوقتي بالشكل العلمي: Background Job هو وحدة شغل بتتنفّذ بشكل غير متزامن (asynchronous) بعيد عن دورة الطلب والرد. الطابور (Queue) بنية بيانات بتشتغل بمبدأ FIFO (الداخل الأول يخرج الأول) بتخزّن المهام لحد ما يبقى فيه worker فاضي يعالجها. وBullMQ مكتبة Node.js بتدير الطوابير دي وبتخزّنها في Redis (قاعدة بيانات في الذاكرة سريعة جداً)، عشان لو السيرفر اتقفل المهام متضيعش.
الخطوات: من صفر لـ worker شغّال
- شغّل Redis. أسهل طريقة بـ Docker:
النتيجة المتوقعة: عندك Redis شغّال على المنفذ 6379.
docker run -d --name redis -p 6379:6379 redis:7 # تأكد إنه شغّال docker exec -it redis redis-cli ping # المفروض يرد: PONG - نصّب المكتبات.
BullMQ بتحتاج اتصال Redis، و express عشان نعمل الـ endpoint.