سلام دوستان. امروز میخوام در مورد یه موضوع خیلی کاربردی در لاراول صحبت کنم که در درجه اول خیلی مهم به نظر نمیرسه ولی ازش استفاده که میکنید میبینید چقد بدون صف زندگی کردن سخته. پس بذارید زود شروع کنم.
صف ها در برنامه نویسی به چه دردی میخورن؟
راستش صف ها جدا از اینکه توی زندگی ما آدم ها خیلی مهم هستن بعضی موقه ها توی کدهامون هم خیلی مهم میشن. مخصوصا اگه معلوم نباشه که هر کی چند دقیقه کارش طول میکشه. اگه بخوام یک مثال عملی بزنم فرض کنید یک تعداد خیلی زیادی کار دارید و میخواید اونها رو انجام بدید و از طرف دیگه مدت زمان انجام شدن هر کدوم از اونها از شروع تا پایان هم مشخص نیست. فرض کنید من یه موتور جستجو دارم که میخوام توی وبسایت ها بخزم و محتوای اونها رو ایندکس کنم و اگه ویدئو و عکسی هست پردازش کنم و ایندکس کنم. اگه محتوا متنی باشه خیلی زود و اگه عکس باشه بیشتر و ویدئو باشه خیلی بیشتر طول میکشه این عملیات تموم بشه. یه راه اینه که یه for
بنویسم و بگم پشت سر هم این کارها رو انجام بده. ولی اگه توی ایتریشن دوم کدم به خطا خورد چی؟ اصلا از کجا بدونم به خطا خورده؟ اگه خواستم اجراهایی که به خطا خوردن رو دوباره اجرا کنم چی؟
صف ها در لاراول به شما این امکانات رو میدن که به راحتی جاب ها رو بذارید توی صف. اگه خطایی بوجود اومد لاگش رو ذخیره میکنن. میتونید با پکیج هاریزون مانیتور کنید که جابهاتون توی چه مرحله ای از اجرا قرار دارن چند بار به خطا خوردن و چند تا از جابها تموم شدن و خیلی چیزای دیگه که توی همین پست میبینیدشون.
توی لاراول میتونید با سیستم های مدیریت صف معروف مثل ردیس کار کنید و کافیه فقط یه کانکشن به ردیس بزنید و بقیه خیلی ساده هست ولی برای مدیریت صف های ساده و سبک میتونید از همون صف دیتابیس استفاده کنید.
استفاده از صف دیتابیس در لاراول
اولین کاری که باید بکنید اینه که جدول هاتون رو ایجاد کنید. برای اینکار توی محیط ترمینال لاراول و توی روت پروژه این دستورها رو ران کنید:
php artisan queue:table
php artisan queue:failed-table
php artisan migrate
با دستور اول یه مایگریشن ایجاد میشه برای ذخیره جاب های صف ها. با دستور دوم یه مایگریشن ایجاد میشه برای جابهایی که به خطا خوردن و با دستور سوم…
خب حالا بذارید یه جاب خیلی ساده بنویسیم. با دستور زیر میتونید یک جاب جدید درست کنید. جابها توی فولدر app/Jobs
قرار میگیرن که اگه دستور زیر رو ران کنید فولدر خودش ساخته میشه.
php artisan make:job MyFirstJob
الان اگه فایل MyFirstJob.php
رو باز کنید یچی مثل این میبینید:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class MyFristJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
}
}
داخل متد handle
این رو بنویسید:
$seconds = rand(0, 15);
sleep($seconds);
Log::info('job ran ' . Carbon::now()->toDateTimeString());
توی این قسمت گفتم که یک عدد تصادفی بین ۰ تا ۱۵ تولید کن و بعد به اندازه اون عدده ثانیه صبر کن و یه خروجی رو توی فایل لاگ بنویس و فرض کنید اون اسلیپ شدنه یه جاب سنگین مثل پردازش ویدیو و… هست. و یادتون نره که Carbon
و Log
رو use
کنید.
گذاشتن جاب در صف
برای گذاشتن جاب توی صف در لاراول کافیه متد dispatch
از اون جاب رو صدا بزنیم. برای مثال توی فایل routes/web.php
قطعه کد زیر رو اضافه کنید:
Route::get('put', function () {
\App\Jobs\MyFristJob::dispatch();
});
گفتم هر بار روت /put
با متد get
فراخوانی شد یدونه از این جاب رو بذار توی صف. پس کافیه روت /put
رو get
کنید. بعد از این کار باید توی جدول jobs
یه رکورد ایجاد شده باشه. فیلد هایی که جدول jobs
داره خیلی پیچیده نیستن و با یه نگاه میتونید ببینید که داره چه اتفاقی میفته.
تنظیمات درایور صف در لاراول
خب حالا نوبت این رسیده که صف رو توی پروژه ران کنیم. ولی قبلش یه سر به فایل config/queue.php
بزنیم. اولین چیزی که احتمالا میبینید خط زیر هست:
'default' => env('QUEUE_CONNECTION', 'sync'),
این خط میگه که کانکشن پیشفرض من برای اجرای صف ها چی باشه که بصورت پیشفرض روی درایور sync
تنظیم شده. درایور sync
که یکم پایینتر هم اینجا و هم توی فایل کانفیگ میبینیدش میگه هر جابی که دیسپچ شد همون لحظه شروع بشه به ران شدن. در واقع اصلا صف حساب نمیشه.
'sync' => [
'driver' => 'sync',
],
یسری کانشکن هم پایین تر از اون و اینسری فقط توی فایل کانفیگ میبینید 🙂 اونها کانکشن های مختلف به سیستم های مدیریت صف مختلف هستن. ما توی اینجا کانکشن پیشفرض رو تنظیمش میکنیم روی database
و پایین تر در قسمت failed
میتونید مشخص کنید که جابهایی که با خطا مواجه میشن کجا ذخیره بشن.
اجرای یک صف در لاراول
برای اجرای صف خیلی ساده دستور زیر رو اجرا کنید:
php artisan queue:work
این دستور شروع میکنه دونه دونه جابهایی که توی جدول jobs
هستند رو اجرا میکنه. و بعد از تموم شدن جابهای صف، بازم منتظر میمونه که جاب جدید dispatch
شه.
اگه فایل لاگتون رو چک کنید باید یچیزی مثل این رو ببینید که نشون میده هر جاب بعد از جاب قبلی اجرا شده.
خوشحال میشم اگه نکته ای هست کامنت کنید. موفق باشید.
ممنون
ساده و قابل فهم
تنکیو
فوق العاده بود
مرسی!