سی ام اس نویسسی ام اس نویسیاد بگیر، سیستم خودتو بنویس
مجلهتماس با ما
سی ام اس نویسسی ام اس نویس

CMS نویس مرجعی برای آموزش برنامه نویسی وب و PHP، توسعه افزونه‌های اختصاصی وردپرس، طراحی ورک‌فلو و اتوماسیون با n8n و توسعه CMS های اختصاصی است. هدف ما ارائه آموزش‌های کاربردی و راهکارهای حرفه‌ای برای توسعه‌دهندگان، کسب‌وکارها و علاقه‌مندان به دنیای برنامه‌نویسی است.

پیوندهای سریع
محصولات فیزیکیمحصولات دیجیتالدوره‌های آموزشی
سی ام اس نویس
مجله سی ام اس نویستماس با ماپنل کاربری
سی ام اس نویس — تمامی حقوق برای سی ام اس نویس محفوظ است. © 1406 تماس با ما09307711941
Queue در Laravel چیست؟ آموزش کامل صف و پردازش پس‌زمینه در لاراول

Queue در Laravel چیست؟ آموزش کامل صف و پردازش پس‌زمینه در لاراول

ممدیر کل سیستم ۱۵ مهر ۱۴۰۵ ۲۳ دقیقه مطالعه ۱ بازدید
Queue در Laravel چیست؟ آموزش کامل صف و پردازش پس‌زمینه در لاراول

در یک پروژه واقعی Laravel، همه عملیات را نمی‌توان یا نباید در همان لحظه‌ای که کاربر درخواست خود را ارسال می‌کند اجرا کرد.

فرض کنید کاربر یک سفارش ثبت می‌کند و سیستم باید همزمان چند کار انجام دهد:

  • ارسال ایمیل تأیید
  • ارسال پیامک
  • تولید فاکتور
  • پردازش تصویر
  • ارسال اطلاعات به یک API خارجی
  • محاسبه گزارش
  • به‌روزرسانی اطلاعات چند جدول
  • پردازش هزاران رکورد

اگر تمام این عملیات مستقیماً داخل Request اجرا شوند، کاربر باید تا پایان آنها منتظر بماند.

اینجاست که Queue در Laravel اهمیت پیدا می‌کند.

Queue به Laravel اجازه می‌دهد کارهای مختلف را در یک صف قرار دهد تا بعداً توسط یک Worker پردازش شوند.

به زبان ساده:


درخواست کاربر

      ↓

ثبت Job در Queue

      ↓

پاسخ سریع به کاربر

      ↓

Queue Worker

      ↓

اجرای Job

در این مقاله یاد می‌گیریم Queue در Laravel چیست، چگونه کار می‌کند، چه Driverهایی دارد، چگونه یک Queue با Database یا Redis راه‌اندازی کنیم، Worker چیست، چگونه Failed Jobها را مدیریت کنیم و چگونه Queue را در محیط Production اجرا کنیم.


# Queue در Laravel چیست؟

Queue یا صف، سیستمی برای قرار دادن کارهای قابل پردازش در یک صف انتظار است.

فرض کنید ۱۰۰۰ کار برای انجام داریم.

به جای اینکه برنامه بخواهد همه آنها را همزمان اجرا کند، می‌توانیم آنها را داخل Queue قرار دهیم:


Job 1

Job 2

Job 3

Job 4

...

Job 1000

سپس یک یا چند Worker این Jobها را پردازش می‌کنند.

بنابراین Queue خودش معمولاً کار را انجام نمی‌دهد؛ بلکه Jobهای منتظر اجرا را نگهداری و در اختیار Worker قرار می‌دهد.


# Queue چه مشکلی را حل می‌کند؟

فرض کنید کاربر در سایت شما یک فرم ثبت سفارش ارسال می‌کند.

بدون Queue ممکن است چنین اتفاقی بیفتد:


ثبت سفارش

    ↓

ارسال ایمیل

    ↓

ارسال پیامک

    ↓

ارتباط با API

    ↓

ساخت PDF

    ↓

ثبت گزارش

    ↓

پاسخ به کاربر

اگر هر عملیات چند ثانیه طول بکشد، کاربر باید مدت زیادی منتظر بماند.

اما با Queue می‌توانیم معماری را تغییر دهیم:


ثبت سفارش

    ↓

Dispatch Job

    ↓

قرار گرفتن Job در Queue

    ↓

پاسخ سریع به کاربر



و همزمان:



Queue Worker

    ↓

دریافت Job

    ↓

اجرای عملیات

این یکی از مهم‌ترین دلایل استفاده از Queue در پروژه‌های Laravel است.


# تفاوت Job و Queue در Laravel چیست؟

این دو مفهوم ارتباط بسیار نزدیکی دارند اما یکسان نیستند.

Job مشخص می‌کند چه کاری باید انجام شود.

Queue مشخص می‌کند این کار در صف پردازش قرار بگیرد.

Worker کار موجود در Queue را دریافت و اجرا می‌کند.

برای مثال:


Job:

ProcessOrder



Queue:

لیست Jobهای منتظر اجرا



Worker:

پردازش ProcessOrder

می‌توان این ساختار را این‌گونه تصور کرد:


Application

     ↓

    Job

     ↓

   Queue

     ↓

  Worker

     ↓

 Execution

در مقاله قبلی به شکل کامل درباره Job در Laravel صحبت کردیم؛ در این مقاله تمرکز اصلی روی زیرساخت Queue و نحوه اجرای آن است.


# Queue Worker چیست؟

Worker برنامه‌ای است که به Queue گوش می‌دهد و Jobهای موجود در آن را پردازش می‌کند.

برای اجرای Worker در Laravel معمولاً از دستور زیر استفاده می‌شود:


php artisan queue:work

پس از اجرای این دستور، Worker شروع می‌کند به بررسی Queue.

اگر Job جدیدی وجود داشته باشد، آن را دریافت و اجرا می‌کند.

به صورت ساده:


Queue

 ├── Job 1

 ├── Job 2

 ├── Job 3

 └── Job 4

       ↓

     Worker

       ↓

    Execution

اگر Worker اجرا نشود، Jobهای Queue معمولاً منتظر می‌مانند تا یک Worker آنها را پردازش کند.


# Queue Driver چیست؟

Laravel از چند روش مختلف برای ذخیره و مدیریت Queue پشتیبانی می‌کند.

به این روش‌ها Queue Driver گفته می‌شود.

بر اساس نیاز پروژه می‌توان از Driverهای مختلف استفاده کرد.

مهم‌ترین گزینه‌هایی که معمولاً با آنها مواجه می‌شویم عبارت‌اند از:

Driverکاربرد
syncاجرای فوری و بدون صف واقعی
databaseذخیره Queue در دیتابیس
redisاستفاده از Redis برای Queue
sqsاستفاده از Amazon SQS
beanstalkdاستفاده از Beanstalkd

برای پروژه‌های معمولی Laravel، database و redis گزینه‌های بسیار مهمی هستند.


# Queue Connection چیست؟

در Laravel تنظیمات Queue در فایل:


config/queue.php

قرار دارد.

اما معمولاً Connection اصلی را از فایل .env مشخص می‌کنیم.

مثلاً:


QUEUE_CONNECTION=database

یا:


QUEUE_CONNECTION=redis

و برای اجرای مستقیم:


QUEUE_CONNECTION=sync

بنابراین Laravel بر اساس QUEUE_CONNECTION متوجه می‌شود که Jobها را چگونه مدیریت کند.


# Queue با Driver sync

در حالت:


QUEUE_CONNECTION=sync

کارها عملاً در همان لحظه اجرا می‌شوند.

مثلاً:


ProcessOrder::dispatch($order->id);

در این حالت عملیات Job در همان Request انجام می‌شود.

پس:


Request

   ↓

Dispatch

   ↓

Job

   ↓

Execution

   ↓

Response

این حالت برای شروع توسعه یا پروژه‌های بسیار ساده مفید است، اما مزیت اصلی Queue یعنی پردازش پس‌زمینه را در اختیار ما قرار نمی‌دهد.


# Database Queue در Laravel

یکی از ساده‌ترین روش‌های راه‌اندازی Queue استفاده از Database است.

در این روش Laravel اطلاعات Jobهای منتظر اجرا را داخل یک جدول دیتابیس ذخیره می‌کند.

مزیت مهم این روش این است که برای شروع نیازی به نصب سرویس جداگانه‌ای مانند Redis ندارید.


# ساخت جدول Queue

برای استفاده از Database Queue باید جدول مربوط به Queue را در دیتابیس داشته باشیم.

در نسخه‌های Laravel که از Migration مربوط به Queue استفاده می‌کنند، می‌توانیم از Artisan کمک بگیریم:


php artisan make:queue-table

سپس Migrationها را اجرا می‌کنیم:


php artisan migrate

بعد از اجرای Migration، جدول Queue در دیتابیس ایجاد می‌شود.

در بسیاری از پروژه‌ها جدولی مانند:


jobs

برای نگهداری Jobهای منتظر اجرا استفاده می‌شود.


# تنظیم Database Queue

در فایل .env:


QUEUE_CONNECTION=database

بعد از تغییر .env، اگر تنظیمات Configuration Cache شده باشد، بهتر است Cache مربوط به Configuration را پاک یا دوباره Cache کنیم:


php artisan config:clear

در محیط Production می‌توان پس از بررسی تنظیمات از:


php artisan config:cache

استفاده کرد.


# اجرای Database Queue

حالا Worker را اجرا می‌کنیم:


php artisan queue:work

سپس در برنامه یک Job را Dispatch می‌کنیم:


ProcessOrder::dispatch($order->id);

Job وارد جدول Queue می‌شود.

Worker آن را پیدا می‌کند و اجرا خواهد کرد.


# چرخه اجرای Queue چگونه است؟

فرآیند کلی را می‌توان این‌گونه نمایش داد:


User Request

      ↓

Dispatch Job

      ↓

Queue Driver

      ↓

Store Job

      ↓

Queue Worker

      ↓

Get Job

      ↓

Execute handle()

      ↓

Delete Job

اگر اجرای Job موفق باشد، Job از صف حذف می‌شود.

اگر اجرای Job با خطا مواجه شود، Laravel بر اساس تنظیمات Retry و Failed Jobs با آن برخورد می‌کند.


# Redis Queue در Laravel چیست؟

Redis یکی از گزینه‌های بسیار محبوب برای Queue است.

Redis یک سیستم ذخیره‌سازی داده در حافظه است که می‌تواند برای مدیریت Queue نیز استفاده شود.

در پروژه‌هایی که حجم Queue بالا است یا به عملکرد بیشتری نیاز داریم، Redis می‌تواند انتخاب بسیار مناسبی باشد.

تنظیم Connection می‌تواند به شکل زیر باشد:


QUEUE_CONNECTION=redis

سپس Worker:


php artisan queue:work redis

را اجرا می‌کنیم.

البته برای استفاده از Redis باید Redis روی محیط اجرای پروژه در دسترس باشد و تنظیمات اتصال آن نیز صحیح باشد.


# Database Queue یا Redis Queue؟

هر دو روش کاربرد خودشان را دارند.

ویژگیDatabaseRedis
نصب سادهبسیار سادهنیازمند Redis
مناسب شروعبلهبله
عملکرد بالامتوسطبسیار خوب
مناسب حجم بالامحدودترمناسب‌تر
نیاز به سرویس جداگانهخیربله
مدیریت Queueهای بزرگمتوسطبسیار مناسب
مناسب Productionبلهبله

اگر پروژه کوچک یا متوسطی دارید و سادگی برایتان اهمیت دارد، Database Queue می‌تواند گزینه مناسبی باشد.

اگر پروژه حجم پردازش بالایی دارد و Redis از قبل در زیرساخت شما وجود دارد، Redis معمولاً انتخاب جذاب‌تری است.


# Queue Worker را چگونه اجرا کنیم؟

دستور اصلی:


php artisan queue:work

این Worker به صورت دائمی به کار خود ادامه می‌دهد و Queue را پردازش می‌کند.

می‌توان مشخصات مختلفی برای Worker تعیین کرد.

مثلاً:


php artisan queue:work --tries=3

یا:


php artisan queue:work --timeout=120

همچنین می‌توان ترکیبی از گزینه‌ها را استفاده کرد.

برای مثال:


php artisan queue:work --tries=3 --timeout=120


# queue:work و queue:listen چه تفاوتی دارند؟

Laravel دستورهای مختلفی برای اجرای Worker دارد.

یکی از دستورهای رایج:


php artisan queue:work

است.

queue:work برای محیط‌های واقعی و Production گزینه متداول‌تری است، زیرا Worker را به شکل پایدار اجرا می‌کند.

در مقابل queue:listen معمولاً بیشتر در سناریوهای توسعه مورد استفاده قرار می‌گیرد و نسبت به queue:work سربار بیشتری دارد.

برای Production معمولاً بهتر است Worker پایدار را با یک Process Manager اجرا کنیم.


# اجرای Queue برای یک Queue مشخص

گاهی پروژه چند Queue مختلف دارد.

مثلاً:


default

emails

notifications

reports

می‌توانیم Worker را برای Queue مشخص اجرا کنیم.

مثلاً:


php artisan queue:work --queue=emails

یا:


php artisan queue:work --queue=emails,notifications,default

در این حالت می‌توانیم اولویت Queueها را نیز کنترل کنیم.

این قابلیت در پروژه‌هایی که Jobهای مختلف با اهمیت‌های متفاوت دارند بسیار مفید است.


# چرا چند Queue داشته باشیم؟

فرض کنید پروژه شما این Jobها را دارد:


SendEmail

GenerateReport

ProcessPayment

ResizeImage

SendNotification

پردازش پرداخت ممکن است بسیار مهم‌تر از Resize کردن یک تصویر باشد.

بنابراین می‌توانیم Queueهای مختلف ایجاد کنیم:


high

default

low

و Jobها را در Queue مناسب قرار دهیم.

مثلاً:


ProcessPayment::dispatch($payment)

    ->onQueue('high');

یا:


GenerateReport::dispatch($report)

    ->onQueue('low');

سپس Worker را با اولویت مناسب اجرا کنیم:


php artisan queue:work --queue=high,default,low


# Retry در Queue چیست؟

ممکن است Job به دلیل یک خطای موقتی شکست بخورد.

برای مثال:


API خارجی در دسترس نیست

        ↓

Job شکست می‌خورد

        ↓

Retry

        ↓

API دوباره در دسترس است

        ↓

Job موفق می‌شود

می‌توان تعداد تلاش‌ها را مشخص کرد.

مثلاً:


public int $tries = 3;

یا هنگام اجرای Worker:


php artisan queue:work --tries=3

این موضوع باعث می‌شود خطاهای موقتی لزوماً باعث شکست نهایی Job نشوند.


# Failed Jobs در Laravel

گاهی Job بعد از تمام Retryها همچنان شکست می‌خورد.

در این حالت باید بتوانیم آن را بررسی کنیم.

Laravel امکان مدیریت Failed Jobs را فراهم می‌کند.

برای مشاهده Failed Jobs:


php artisan queue:failed

این دستور اطلاعات Jobهای شکست‌خورده را نمایش می‌دهد.


# Retry کردن Failed Job

اگر مشکل برطرف شده باشد، می‌توانیم Job را دوباره اجرا کنیم:


php artisan queue:retry ID

برای مثال:


php artisan queue:retry 15

یا در صورت نیاز می‌توان Jobهای بیشتری را Retry کرد.

این قابلیت در Production بسیار کاربردی است.


# پاک کردن Failed Jobs

اگر Job دیگر مورد نیاز نیست، می‌توان آن را حذف کرد:


php artisan queue:forget ID

و برای پاک‌سازی Failed Jobs نیز می‌توان از:


php artisan queue:flush

استفاده کرد.


# Queue Timeout چیست؟

فرض کنید یک Job به دلیل مشکل API یا پردازش بسیار سنگین برای مدت نامحدودی اجرا شود.

این موضوع می‌تواند Worker را برای مدت زیادی درگیر کند.

به همین دلیل باید Timeout مناسب داشته باشیم.

مثلاً:


php artisan queue:work --timeout=120

یا داخل Job:


public int $timeout = 120;

مقدار مناسب Timeout به نوع Job بستگی دارد.


# Queue و Jobهای سنگین

Queue برای پردازش کارهای سنگین بسیار مفید است.

برای مثال:


پردازش 100000 محصول

پردازش فایل Excel

تولید گزارش بزرگ

پردازش تصاویر

ارسال تعداد زیادی ایمیل

همگام‌سازی اطلاعات با API

بهتر است چنین کارهایی را به چند Job کوچک‌تر تقسیم کنیم.

مثلاً به جای:


Import100000ProductsJob

می‌توانیم داده‌ها را به Batchهای کوچک تقسیم کنیم:


ImportProductsChunk 1

ImportProductsChunk 2

ImportProductsChunk 3

...

این کار مدیریت منابع را بسیار بهتر می‌کند.


# Queue و ارسال ایمیل

یکی از رایج‌ترین کاربردهای Queue ارسال ایمیل است.

فرض کنید بعد از ثبت سفارش باید ایمیل ارسال شود.

به جای اینکه کاربر منتظر ارسال ایمیل بماند، می‌توانیم ارسال ایمیل را Queue کنیم.

مثلاً:


SendOrderEmail::dispatch($order->id);

در این حالت:


ثبت سفارش

   ↓

پاسخ سریع

   ↓

Queue

   ↓

SendOrderEmail

   ↓

ارسال ایمیل

این معماری مخصوصاً در فروشگاه‌های اینترنتی بسیار کاربردی است.


# Queue و Notification

Notificationهای Laravel نیز می‌توانند در معماری Queue استفاده شوند.

مثلاً فرض کنید باید برای هزار کاربر Notification ارسال کنیم.

به جای اینکه همه Notificationها را در Request اصلی اجرا کنیم، می‌توانیم آنها را به پردازش غیرهمزمان بسپاریم.

این روش فشار روی Request اصلی را کاهش می‌دهد.


# Queue و APIهای خارجی

یکی از بهترین کاربردهای Queue، ارتباط با APIهای خارجی است.

فرض کنید بعد از ثبت محصول باید اطلاعات آن را به یک سرویس خارجی ارسال کنیم.

اگر API خارجی کند باشد:


Request

   ↓

API خارجی

   ↓

10 ثانیه انتظار

تجربه کاربر خراب می‌شود.

اما:


Request

   ↓

Dispatch Job

   ↓

Response

و بعد:


Worker

   ↓

API خارجی

باعث می‌شود سرعت پاسخ به کاربر مستقل‌تر از سرعت API خارجی شود.


# Queue و Jobهای Idempotent

یکی از نکات بسیار مهم در طراحی Queue این است که نباید فرض کنیم هر Job دقیقاً یک بار اجرا می‌شود.

ممکن است Job به دلایل مختلف دوباره اجرا شود.

بنابراین عملیات حساس باید تا حد امکان Idempotent باشند.

مثلاً در عملیات پرداخت نباید اجرای دوباره Job باعث ایجاد دو تراکنش شود.

بهتر است قبل از انجام عملیات بررسی کنیم که آیا قبلاً انجام شده است یا خیر.

مثلاً:


if ($payment->status === 'paid') {

    return;

}

این موضوع در سیستم‌های مالی اهمیت بسیار زیادی دارد.


# Queue و Database Transaction

یکی از موارد حساس، Dispatch کردن Job درون Transaction است.

مثلاً:


DB::transaction(function () use ($order) {



    $order->update([

        'status' => 'processing',

    ]);



    ProcessOrder::dispatch($order->id);

});

اگر Worker بسیار سریع باشد، ممکن است Job قبل از Commit شدن Transaction اجرا شود.

در نتیجه باید در معماری‌های حساس دقت کنیم Job چه زمانی قابل پردازش شود.

Laravel امکاناتی برای Dispatch کردن Job بعد از Commit شدن Transaction در اختیار توسعه‌دهنده قرار می‌دهد.

این موضوع مخصوصاً در پروژه‌های مالی، سفارش، موجودی و سیستم‌های حساس اهمیت زیادی دارد.


# Queue Worker در Production

در محیط توسعه می‌توانیم Worker را مستقیماً اجرا کنیم:


php artisan queue:work

اما در Production نمی‌توانیم انتظار داشته باشیم یک ترمینال باز بماند و Worker همیشه فعال باشد.

اگر Process متوقف شود، Queue نیز متوقف خواهد شد.

بنابراین در Production باید Worker را با یک Process Manager مدیریت کنیم.

یکی از راهکارهای رایج استفاده از Supervisor است.

ساختار کلی:


Linux Server

     ↓

Supervisor

     ↓

Laravel Queue Worker

     ↓

Queue

Supervisor می‌تواند Worker را اجرا نگه دارد و اگر Worker متوقف شد، آن را دوباره اجرا کند.


# چرا نباید Queue Worker را فقط با SSH اجرا کنیم؟

فرض کنید با SSH وارد سرور شوید و اجرا کنید:


php artisan queue:work

اگر اتصال SSH قطع شود، بسته به نحوه اجرای Process ممکن است Worker نیز متوقف شود.

برای Production بهتر است اجرای Worker را به Process Manager بسپاریم.

به همین دلیل Supervisor یا راهکارهای مدیریت Process اهمیت زیادی دارند.


# Restart کردن Worker بعد از Deploy

یک نکته مهم در Production این است که Workerها Processهای طولانی‌مدت هستند.

اگر کد جدیدی Deploy کنیم، Worker قبلی ممکن است همچنان کد قبلی را در حافظه داشته باشد.

به همین دلیل بعد از Deploy معمولاً Workerها را Restart می‌کنیم:


php artisan queue:restart

این دستور به Workerها اعلام می‌کند پس از اتمام Job فعلی، خودشان را Restart کنند.

در نتیجه Workerهای جدید با نسخه جدید کد اجرا خواهند شد.


# Queue Worker و Memory Limit

Workerها ممکن است مدت زیادی فعال باشند.

اگر Jobها به مرور حافظه مصرف کنند، ممکن است Worker بیش از حد RAM مصرف کند.

برای همین می‌توان Memory Limit تعیین کرد.

مثلاً:


php artisan queue:work --memory=512

در این حالت Worker در صورت عبور از محدوده مشخص‌شده، متوقف می‌شود تا Process Manager بتواند آن را دوباره راه‌اندازی کند.

این موضوع برای Production بسیار مهم است.


# Queue Worker و تعداد تلاش‌ها

می‌توانیم تعداد تلاش Job را از Worker نیز کنترل کنیم:


php artisan queue:work --tries=3

اما برای Jobهای مختلف ممکن است تعداد Retry متفاوتی نیاز داشته باشیم.

مثلاً:


Payment Job → 3 تلاش

Email Job → 5 تلاش

Report Job → 2 تلاش

به همین دلیل بهتر است سیاست Retry بر اساس اهمیت و ماهیت هر Job طراحی شود.


# مدیریت Queue با چند Worker

اگر تعداد Jobها زیاد باشد، یک Worker ممکن است کافی نباشد.

فرض کنید:


10000 Job

در Queue داریم.

یک Worker ممکن است نتواند آنها را با سرعت مناسب پردازش کند.

می‌توان چند Worker اجرا کرد:


Worker 1 ──┐

Worker 2 ──┤

Worker 3 ──┼── Queue

Worker 4 ──┤

Worker 5 ──┘

در این حالت Jobها سریع‌تر پردازش می‌شوند.

تعداد Worker مناسب به مواردی مانند:

  • CPU
  • RAM
  • تعداد Jobها
  • زمان اجرای Job
  • نوع عملیات
  • نوع Queue Driver

بستگی دارد.


# Queue و Redis در پروژه‌های بزرگ

وقتی تعداد Jobها زیاد شود، Database Queue ممکن است دیگر بهترین انتخاب نباشد.

در چنین شرایطی Redis می‌تواند گزینه مناسبی باشد.

معماری می‌تواند چنین شکلی داشته باشد:


Laravel Application

       ↓

      Redis

       ↓

   Queue Jobs

       ↓

Worker 1

Worker 2

Worker 3

       ↓

   Processing

Redis معمولاً در معماری‌هایی که تعداد زیادی Job باید با سرعت بالا پردازش شوند، کاربرد زیادی دارد.

در مقاله بعدی این کلاستر به شکل اختصاصی سراغ Redis در Laravel خواهیم رفت.


# Queue Monitoring چیست؟

در پروژه‌های Production فقط اجرای Queue کافی نیست.

باید بتوانیم وضعیت Queue را نیز بررسی کنیم.

مواردی که بهتر است مانیتور شوند عبارت‌اند از:

  • تعداد Jobهای منتظر
  • تعداد Jobهای شکست‌خورده
  • زمان پردازش Job
  • تعداد Retry
  • وضعیت Workerها
  • مصرف CPU
  • مصرف RAM
  • طول Queue

در پروژه‌های بزرگ، Monitoring Queue اهمیت زیادی پیدا می‌کند.


# Laravel Horizon چیست؟

برای پروژه‌هایی که از Redis به عنوان Queue استفاده می‌کنند، Laravel Horizon یکی از ابزارهای مهم اکوسیستم Laravel است.

Horizon یک داشبورد و سیستم مدیریت برای Redis Queue در Laravel ارائه می‌کند.

با Horizon می‌توان اطلاعاتی مانند:

  • وضعیت Queue
  • Jobهای پردازش‌شده
  • Jobهای شکست‌خورده
  • زمان پردازش
  • تعداد Jobها
  • Workerها

را بهتر مشاهده و مدیریت کرد.

برای پروژه‌های کوچک ممکن است استفاده از Horizon ضروری نباشد، اما در پروژه‌هایی که Queue اهمیت زیادی دارد می‌تواند بسیار ارزشمند باشد.


# Queueهای مختلف برای بخش‌های مختلف سیستم

در پروژه‌های حرفه‌ای بهتر است همه Jobها را داخل یک Queue قرار ندهیم.

مثلاً:


high

default

low

emails

reports

سپس Workerهای مختلف داشته باشیم:


Worker A → high

Worker B → default

Worker C → emails

Worker D → reports

این معماری باعث می‌شود عملیات مهم‌تر منابع مورد نیاز خود را داشته باشند.

مثلاً اگر تولید گزارش سنگین باشد، نباید باعث شود پردازش پرداخت‌های کاربران متوقف شود.


# اشتباهات رایج در استفاده از Queue

۱. اجرای Worker بدون Process Manager

در Production نباید فقط به یک Terminal وابسته باشیم.


۲. قرار دادن اطلاعات بسیار زیاد داخل Job

Job را تا حد امکان سبک نگه دارید و فقط اطلاعات مورد نیاز را منتقل کنید.


۳. نداشتن Timeout

Jobی که هیچ محدودیتی ندارد می‌تواند Worker را برای مدت زیادی اشغال کند.


۴. Retry نامناسب

Retry بیش از حد می‌تواند فشار بیشتری روی سیستم یا API خارجی ایجاد کند.


۵. نادیده گرفتن Failed Jobs

در Production باید Failed Jobs را بررسی و مانیتور کنیم.


۶. استفاده از یک Queue برای همه چیز

Jobهای مهم و کم‌اهمیت بهتر است در صورت نیاز Queueهای جداگانه داشته باشند.


۷. فراموش کردن Restart Worker بعد از Deploy

Workerهای قدیمی ممکن است کد قدیمی را اجرا کنند.

پس بعد از Deploy باید چرخه Restart Worker را در فرآیند Deployment در نظر بگیریم.


۸. اجرای عملیات غیر Idempotent بدون کنترل

به‌خصوص در پرداخت، موجودی و تراکنش مالی، اجرای دوباره Job می‌تواند مشکل جدی ایجاد کند.


# یک معماری پیشنهادی برای پروژه Laravel

برای یک پروژه متوسط می‌توان چنین ساختاری داشت:


Laravel Application

        │

        ├── Web Request

        │

        └── Dispatch Job

                │

                ↓

             Queue

                │

        ┌───────┴───────┐

        ↓               ↓

     Worker 1        Worker 2

        │               │

        └───────┬───────┘

                ↓

              Job

                ↓

             Service

                ↓

       Database / API

اگر حجم سیستم بیشتر شود:


Laravel

   ↓

Redis

   ↓

Queue

   ↓

┌─────────┬─────────┬─────────┐

Worker 1  Worker 2  Worker 3

   ↓         ↓         ↓

 Jobs      Jobs      Jobs

و برای مدیریت بهتر می‌توان Horizon و Process Manager را نیز به این معماری اضافه کرد.


# چه زمانی از Database Queue استفاده کنیم؟

Database Queue گزینه مناسبی است اگر:

  • پروژه کوچک یا متوسط است.
  • Redis در دسترس ندارید.
  • سادگی برایتان اهمیت دارد.
  • حجم Queue خیلی زیاد نیست.
  • نمی‌خواهید سرویس اضافی نصب کنید.

مثلاً برای یک سایت شرکتی یا فروشگاه متوسط ممکن است Database Queue کاملاً کافی باشد.


# چه زمانی Redis Queue انتخاب بهتری است؟

Redis معمولاً زمانی جذاب‌تر می‌شود که:

  • حجم Jobها زیاد باشد.
  • سرعت Queue اهمیت زیادی داشته باشد.
  • Workerهای متعدد داشته باشید.
  • Redis از قبل در معماری پروژه استفاده شود.
  • نیاز به Queue Monitoring حرفه‌ای داشته باشید.
  • پروژه مقیاس‌پذیر باشد.

برای پروژه‌های SaaS، Marketplace، سیستم‌های اتوماسیون و سرویس‌هایی با پردازش زیاد، Redis می‌تواند انتخاب بسیار مناسبی باشد.


# راه‌اندازی سریع Database Queue

اگر بخواهیم یک نمونه ساده داشته باشیم:

مرحله اول: تنظیم Connection

در .env:


QUEUE_CONNECTION=database

مرحله دوم: ساخت جدول Queue


php artisan make:queue-table

مرحله سوم: اجرای Migration


php artisan migrate

مرحله چهارم: ساخت Job


php artisan make:job ProcessOrder

مرحله پنجم: Dispatch


ProcessOrder::dispatch($order->id);

مرحله ششم: اجرای Worker


php artisan queue:work

حالا Worker Job را دریافت و پردازش می‌کند.


# چگونه مطمئن شویم Queue کار می‌کند؟

یک Job آزمایشی ایجاد کنید:


php artisan make:job TestQueue

داخل handle():


public function handle(): void

{

    \Log::info('Test Queue Job Executed');

}

سپس:


TestQueue::dispatch();

Worker را اجرا کنید:


php artisan queue:work

بعد فایل Log Laravel را بررسی کنید.

اگر پیام مربوط به Job را مشاهده کردید، Queue به درستی Job را پردازش کرده است.


# Queue در Laravel برای چه پروژه‌هایی ضروری است؟

استفاده از Queue تقریباً در هر پروژه بزرگ Laravel اهمیت پیدا می‌کند، اما برای بعضی پروژه‌ها اهمیت آن بسیار بیشتر است.

فروشگاه اینترنتی

برای:

  • ایمیل سفارش
  • پیامک
  • فاکتور
  • پردازش پرداخت
  • همگام‌سازی محصولات

SaaS

برای:

  • پردازش Subscription
  • گزارش‌گیری
  • Notification
  • عملیات زمان‌بر

Marketplace

برای:

  • پردازش سفارش
  • محاسبه کمیسیون
  • تسویه
  • Notification
  • گزارش فروش

سیستم‌های اتوماسیون

برای:

  • API
  • Webhook
  • پردازش داده
  • اجرای Workflow
  • ارتباط با سرویس‌های خارجی

# جمع‌بندی

Queue در Laravel یکی از مهم‌ترین ابزارها برای اجرای عملیات غیرهمزمان و مدیریت پردازش‌های زمان‌بر است.

ساختار اصلی آن را می‌توان این‌گونه خلاصه کرد:


Job

 ↓

Queue

 ↓

Worker

 ↓

Execution

Laravel Driverهای مختلفی برای Queue ارائه می‌دهد و از جمله مهم‌ترین گزینه‌ها می‌توان به:

  • sync
  • database
  • redis
  • sqs
  • beanstalkd

اشاره کرد.

برای پروژه‌های ساده، Database Queue می‌تواند انتخاب مناسبی باشد و برای پروژه‌های بزرگ‌تر و پرترافیک، Redis معمولاً گزینه قدرتمندتری است.

اجرای Worker نیز با دستور:


php artisan queue:work

انجام می‌شود.

اما در Production بهتر است Worker را به یک Process Manager مانند Supervisor بسپاریم و مواردی مانند:

  • Retry
  • Timeout
  • Failed Jobs
  • Memory
  • Restart
  • چند Worker
  • Queueهای مختلف
  • Idempotency

را نیز به درستی مدیریت کنیم.

در نهایت، Queue فقط یک ابزار برای سریع‌تر شدن سایت نیست؛ بلکه بخشی از معماری یک برنامه Laravel حرفه‌ای است که کمک می‌کند عملیات سنگین، زمان‌بر و غیرضروری برای Request اصلی از مسیر اجرای مستقیم خارج شوند.


سوالات متداول Queue در Laravel

Queue در Laravel چیست؟

Queue سیستمی برای قرار دادن Jobها در صف و پردازش آنها توسط Worker است.

چگونه Queue را در Laravel فعال کنیم؟

ابتدا باید QUEUE_CONNECTION را در .env تنظیم کنیم و سپس Driver موردنظر را پیکربندی کنیم.

چگونه Worker را اجرا کنیم؟

با دستور:


php artisan queue:work

Database Queue بهتر است یا Redis؟

برای پروژه‌های ساده و متوسط Database Queue می‌تواند کافی باشد؛ برای حجم پردازش بالاتر و معماری‌های حرفه‌ای، Redis معمولاً گزینه مناسب‌تری است.

اگر Queue Worker متوقف شود چه اتفاقی می‌افتد؟

Jobهای پردازش‌نشده در Queue باقی می‌مانند و پس از راه‌اندازی مجدد Worker می‌توانند پردازش شوند؛ جزئیات رفتار به Driver و تنظیمات Job بستگی دارد.

چگونه Failed Jobها را مشاهده کنیم؟

با:


php artisan queue:failed

چگونه یک Failed Job را دوباره اجرا کنیم؟

با:


php artisan queue:retry ID

آیا Queue برای پروژه‌های کوچک لازم است؟

نه همیشه. اما حتی در پروژه‌های کوچک نیز برای عملیات‌هایی مثل ارسال ایمیل، Notification یا ارتباط با API خارجی می‌تواند بسیار مفید باشد.

آیا Queue همان Job است؟

خیر. Job کاری است که باید انجام شود؛ Queue محل یا سازوکار صف‌بندی آن کار است و Worker وظیفه اجرای آن را بر عهده دارد.

نظرات (0)

نظرات پس از تأیید مدیر نمایش داده می‌شوند

هنوز نظری ثبت نشده است؛ اولین نفر باشید!

مقالات مرتبط

ساخت CMS با Laravel 12؛ آموزش ساخت سیستم مدیریت محتوا از صفر

ساخت CMS با Laravel 12؛ آموزش ساخت سیستم مدیریت محتوا از صفر

۲۴ دقیقه
ساخت فروشگاه اینترنتی با Laravel 12؛ آموزش پروژه‌محور از صفر تا طراحی هسته فروشگاه

ساخت فروشگاه اینترنتی با Laravel 12؛ آموزش پروژه‌محور از صفر تا طراحی هسته فروشگاه

۲۲ دقیقه
ساخت Marketplace با Laravel؛ آموزش طراحی فروشگاه چندفروشندگی

ساخت Marketplace با Laravel؛ آموزش طراحی فروشگاه چندفروشندگی

۲۲ دقیقه
مدیریت Queueهای سنگین در Laravel؛ آموزش پردازش کارهای طولانی

مدیریت Queueهای سنگین در Laravel؛ آموزش پردازش کارهای طولانی

۲۲ دقیقه