Featured blog image
236 كلمة 2 دقيقة للقراءة

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 نقاط مهمين

  1. ShouldQueue : معناها إن الـ job ده المفروض يتضاف للـ queue مش يتنفذ فورًا.
  2. handle() : هنا بتحط الكود اللي يتنفذ لما الـ job يشتغل.
  3. __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);

اللي بيحصل هنا بالضبط:

  1. Laravel بياخد الكائن (SendWelcomeEmail)

  2. يحوّله إلى مهمة محفوظة داخل جدول jobs (لو driver = database)

  3. يستنى الـ 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 وإعادة المحاولة



شارك الآن ؟
تواصل معي