Laravel Queues قوائم الإنتظار في لارافيل في خطوات بسيطة
اولا ما هي قوائم الإنتظار Queues ؟
خلينا نبص على المشكلة اللي بتحلّها الـ Queue تخيّل عندك صفحة تسجيل مستخدم جديد، وبعد التسجيل بتبعتله إيميل ترحيبي.
لو الإيميل بيتبعت مباشرة داخل نفس الـ request، المستخدم هيستنى لحد ما الإيميل يتبعت بالكامل قبل ما الصفحة ترد عليه — ممكن ياخد ثانيتين أو أكتر.
دي تجربة سيئة جدًا للمستخدم.
الحل؟
بدل ما تبعت الإيميل فورًا، Laravel يسمحلك إنك تضيف العملية (SendWelcomeEmail) في Queue.
يعني بتقول للنظام: “خلي الـ Job ده يتنفذ لاحقًا في الخلفية، بس خلّي المستخدم ياخد الرد فورًا.”
الفكرة ببساطة:
Queue = طابور مهام waiting for execution.
Job = المهمة نفسها (كود صغير بينفذ حاجة واحدة).
Worker = الشخص اللي بياخد المهام من الطابور وينفذها (process شغالة في الخلفية).
ليه دا مفيد :
تحسين السرعة — الطلب الرئيسي بيرجع بسرعة للمستخدم.
توزيع الحمل — بدل ما السيرفر ينفذ كل حاجة في نفس اللحظة، بيوزع المهام بالتدريج.
الثبات (Reliability) — لو حصل خطأ أثناء تنفيذ job، Laravel بيقدر يحاول تاني أو يحفظها كـ failed.
إعداد الـ Queue في Laravel
علشان Laravel يشتغل بالـ queues، محتاج تحدد الـ driver اللي هيستخدمه الـ driver هو المكان اللي هيتخزن فيه الـ jobs (الطابور نفسه).
Laravel بيدعم كذا driver، أهمهم:
sync
→ ينفذ الـ job فورًا (من غير Queue فعلًا).
database
→ يخزن الـ jobs في جدول داخل قاعدة البيانات.
redis
→ سريع ومناسب للحمل الكبير.
إعداد الملف .env
هنفتح ملف ال .env ونعدل السطر دا عشان يكون بالشكل دا وهنا هنشغل علي driver database
QUEUE_CONNECTION=database
ضبط ملف config/queue.php
الملف ده بيحتوي على كل الإعدادات الخاصة بكل driver فيه جزء اسمه connections
:
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
],
- driver : اسم الـ driver المستخدم زي ما قولنا ( database , sync , redis ) وغيرة
- table : اسم الجدول اللي هيخزن الـ jobs
- retry_after : الوقت اللي بعدها Laravel يعتبر الـ job فشل لو ما خلصش
إنشاء جدول الـ jobs
بما إننا اخترنا database
، لازم ننشئ الجدول اللي هيخزن المهام:
php artisan queue:table
php artisan migrate
ده بيعمل جدول اسمه jobs
فيه كل التفاصيل عن المهام اللي لسه ما اشتغلتش.
إنشاء الـ Job في Laravel
الـ Job هو القطعة اللي بتحطها في الـ queue — الكود اللي المفروض يتنفّذ في الخلفية.
Laravel بيخليه class مستقل ومنظم، بحيث يكون كل Job مسؤول عن مهمة واحدة محددة.
نيجي نعمل Job جديدة تتماشي مع المثال بتاعنا
php artisan make:job SendWelcomeEmail
هيتم انشاء ملف جديد في المسار التالي
app/Jobs/SendWelcomeEmail.php
هيبقى شكله كده مبدئيا:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SendWelcomeEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(public $user) {}
public function handle(): void
{
// الكود اللي هيتنفذ هنا
}
}
في الملف الي هيتعمل هنركز علي 3 نقاط مهمين
ShouldQueue
: معناها إن الـ job ده المفروض يتضاف للـ queue مش يتنفذ فورًا.handle()
: هنا بتحط الكود اللي يتنفذ لما الـ job يشتغل.__construct()
: تستخدمه لو عايز تبعت بيانات للـ job (زي الـ user اللي لسه سجل مثلاً).
مثال عملي :
خلينا نقول عندك User
لسه عامل تسجيل، وعايز تبعتله إيميل ترحيبي:
public function handle(): void
{
\Mail::to($this->user->email)
->send(new \App\Mail\WelcomeMail($this->user));
}
يبقى كده الكود اللي جوا handle()
هو اللي هيتنفذ لما الـ worker يشتغل.
تمرير البيانات وقت الانشاء : في الكود اللي بينادي الـ Job (مثلاً جوه Controller):
SendWelcomeEmail::dispatch($user);
أهو كده انت أضفت الـ job ده للـ queue وبكده بدل ما تبعته فورًا,
إرسال الـ Job إلى الـ Queue
زي ما شفنا قبل، تقدر تستخدم dispatch()
:
SendWelcomeEmail::dispatch($user);
اللي بيحصل هنا بالضبط:
-
Laravel بياخد الكائن (
SendWelcomeEmail
) -
يحوّله إلى مهمة محفوظة داخل جدول
jobs
(لو driver = database) -
يستنى الـ worker ييجي ينفذه بعدين
تشغيل الـ Worker
ده العامل اللي بياخد المهام وينفذها واحدة واحدة
php artisan queue:work
ده بيبدأ process تفضل شغالة وتراقب الـ queue، وكل ما تلاقي Job جديد تنفّذه.
لو عايز توقفها بعد تنفيذ مهمة واحدة بس:
php artisan queue:work --once
إعادة تشغيل الـ Workers
أحيانًا بتغيّر كود الـ Jobs أثناء التطوير، وساعتها لازم تعيد تشغيل الـ workers:
php artisan queue:restart
Laravel بيبعت signal لكل الـ workers يخليهم يخلصوا الشغل اللي في إيديهم وبعدين يعيدوا التشغيل
التعامل مع فشل ال Job وإعادة المحاولة