Laravel'da xat yuborish, SMS jo'natish, hisobot tayyorlash yoki rasmlarni qayta ishlash kabi og'ir vazifalar odatda navbatga (queue) qo'yiladi, takrorlanadigan ishlar esa rejalashtiruvchiga (scheduler) topshiriladi. Lokal kompyuterda dasturchi php artisan queue:work buyrug'ini terminalda ishga tushiradi va hammasi joyida bo'ladi. Serverga joylangandan keyin esa navbatdagi vazifalar bajarilmay to'planib qoladi, chunki ularni o'qiydigan jarayon hech kim tomonidan ishga tushirilmagan. Ushbu maqolada navbat ishchisi va rejalashtiruvchini serverda qanday qilib doimiy va ishonchli ishlatish mumkinligini ko'rib chiqamiz.
Queue va scheduler aslida qanday ishlaydi
Navbat tizimi ikki qismdan iborat. Ilova vazifani navbatga yozadi, masalan, ma'lumotlar bazasidagi jobs jadvaliga yoki Redis'ga. Alohida ishlab turgan ishchi jarayon, ya'ni queue:work, shu navbatni kuzatib boradi va har bir vazifani olib bajaradi. Agar ishchi jarayon ishlamasa, vazifalar yo'qolmaydi, lekin hech qachon bajarilmaydi ham. Rejalashtiruvchi esa butunlay boshqacha ishlaydi: Laravel o'zi vaqtni kuzatmaydi, uni har daqiqada tashqaridan php artisan schedule:run buyrug'i bilan uyg'otish kerak. Bu buyruq qaysi vazifaning vaqti kelganini tekshiradi va faqat o'shalarni bajaradi.
Amaliy misol: Toshkentdagi xususiy klinika misol.uz saytida bemorlar qabulga yoziladi. Yozilish paytida tasdiq SMS navbatga qo'yiladi, har kuni ertalab soat 9 da esa ertangi qabul haqida eslatmalar yuboriladi. Birinchi vazifa uchun doimiy ishlaydigan navbat ishchisi, ikkinchisi uchun esa har daqiqada uyg'otiladigan rejalashtiruvchi kerak. Ikkalasidan biri sozlanmagan bo'lsa, bemorlar xabar olmaydi va klinika buni faqat shikoyatlardan keyin biladi.
Navbat drayverini tanlash va tayyorlash
Oddiy loyihalar uchun eng qulay drayver ma'lumotlar bazasi, chunki u qo'shimcha xizmat talab qilmaydi. .env faylida QUEUE_CONNECTION=database qiymatini qo'ying. Laravel 11'da jobs va failed_jobs jadvallari standart migratsiyalar tarkibida keladi, eski versiyalarda esa ularni alohida buyruq bilan yaratish kerak. Yuklama katta bo'lsa yoki vazifalar soni minglab bo'lsa, Redis tezroq ishlaydi, ammo uni VPS'da o'zingiz o'rnatishingiz kerak bo'ladi.
# Laravel 10 va undan eski versiyalarda
php artisan queue:table
php artisan queue:failed-table
php artisan migrate --force
Rejalashtiruvchi uchun bitta cron qatori
Laravel 11'da rejalashtirilgan vazifalar routes/console.php faylida, eski versiyalarda esa app/Console/Kernel.php ichidagi schedule metodida yoziladi. Klinika misolida eslatmalar quyidagicha belgilanadi:
use Illuminate\Support\Facades\Schedule;
Schedule::command('reminders:send')
->dailyAt('09:00')
->timezone('Asia/Tashkent');
Vaqt mintaqasiga alohida e'tibor bering: server UTC bo'yicha ishlashi mumkin va timezone ko'rsatilmasa, eslatmalar besh soat kechikib ketadi. Bu vazifalarni uyg'otish uchun serverda faqat bitta cron qatori kerak, qolgan hamma jadvalni Laravel o'zi boshqaradi:
* * * * * cd /var/www/misol && php artisan schedule:run >> /dev/null 2>&1
Oddiy hostingda bu qatorni ISPmanager panelidagi rejalashtiruvchi (cron) bo'limida qo'shasiz. Muhim jihat: hostingda bir nechta PHP versiyasi o'rnatilgan bo'lishi mumkin va php buyrug'i siz kutgan versiyani chaqirmasligi mumkin. Bunday holda to'liq yo'lni yozing, masalan /opt/php82/bin/php; aniq yo'lni sayt.uz texnik yordami orqali bilib olishingiz mumkin.
VPS'da Supervisor bilan doimiy ishchi
queue:work uzoq yashaydigan jarayon, u xotira oqishi, server qayta ishga tushishi yoki kutilmagan xato tufayli to'xtab qolishi mumkin. Supervisor aynan shunday jarayonlarni kuzatib turadi va to'xtasa, darhol qayta ishga tushiradi. Ubuntu yoki Debian'da u quyidagicha o'rnatiladi:
sudo apt install supervisor
So'ng /etc/supervisor/conf.d/misol-worker.conf faylini yarating:
[program:misol-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/misol/artisan queue:work database --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/misol/storage/logs/worker.log
stopwaitsecs=3600
Bu yerda numprocs=2 ikkita parallel ishchi ochadi, --max-time=3600 esa har bir ishchini bir soatdan keyin o'zi to'xtashga majbur qiladi, Supervisor uni yangidan ishga tushiradi. Bu xotira asta-sekin to'lib borishining oldini oladi. stopwaitsecs qiymati eng uzun vazifangizdan katta bo'lishi kerak, aks holda to'xtatish paytida yarim bajarilgan vazifa uzilib qoladi. Konfiguratsiyani yuklash uchun quyidagi buyruqlar ishlatiladi:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start "misol-worker:*"
sudo supervisorctl status
Supervisor bo'lmagan oddiy hostingda nima qilish kerak
Shared hostingda odatda Supervisor o'rnatib bo'lmaydi va doimiy fon jarayonlarini ushlab turish ham cheklangan. Bunday holda navbatni rejalashtiruvchining o'zi orqali qayta ishlash mumkin: har daqiqada ishchi ishga tushadi, navbatdagi hamma vazifani bajaradi va navbat bo'shagach o'zi chiqib ketadi.
Schedule::command('queue:work --stop-when-empty --max-time=50')
->everyMinute()
->withoutOverlapping();
withoutOverlapping oldingi ishchi hali tugamagan bo'lsa, yangisini ochmaydi, shuning uchun jarayonlar ustma-ust to'planib qolmaydi. Bu usulda vazifalar bir daqiqagacha kechikishi mumkin, lekin tasdiq xatlari va SMS uchun bu odatda sezilmaydi. Agar loyihada video konvertatsiya yoki katta eksport kabi bir necha daqiqa davom etadigan vazifalar bo'lsa, VPS'ga o'tish to'g'riroq yechim bo'ladi.
Deploy, xatolik va nazorat
Navbat ishchisi ilova kodini xotiraga bir marta yuklaydi va yangi kodni o'zi ko'rmaydi. Shuning uchun har bir deploy'dan keyin quyidagi buyruqni bajaring, ishchilar joriy vazifani tugatib, yumshoq to'xtaydi va Supervisor ularni yangi kod bilan qayta ochadi:
php artisan queue:restart
Uch marta urinishdan keyin ham bajarilmagan vazifalar failed_jobs jadvaliga tushadi. Ularni php artisan queue:failed bilan ko'rib chiqish va sababini tuzatgandan keyin php artisan queue:retry all bilan qayta yuborish mumkin. Vaqti-vaqti bilan storage/logs dagi loglarni ham ko'zdan kechiring: SMS shlyuzi javob bermayotgani yoki pochta paroli o'zgargani ko'pincha aynan shu yerda birinchi bo'lib ko'rinadi. Shunda klinika bemorlari xabarni o'z vaqtida oladi, siz esa muammoni mijozlardan oldin ko'rasiz.