⏱️
Хостинг

Laravel queue ва scheduler'ни серверда ишлатиш: cron, Supervisor ва оддий хостинг

10.11.2026
← Барча мақолалар

Laravel'да хат юбориш, SMS жўнатиш, ҳисобот тайёрлаш ёки расмларни қайта ишлаш каби оғир вазифалар одатда навбатга (queue) қўйилади, такрорланадиган ишлар эса режалаштирувчига (scheduler) топширилади. Локал компьютерда дастурчи php artisan queue:work буйруғини терминалда ишга туширади ва ҳаммаси жойида бўлади. Серверга жойлангандан кейин эса навбатдаги вазифалар бажарилмай тўпланиб қолади, чунки уларни ўқийдиган жараён ҳеч ким томонидан ишга туширилмаган. Ушбу мақолада навбат ишчиси ва режалаштирувчини серверда қандай қилиб доимий ва ишончли ишлатиш мумкинлигини кўриб чиқамиз.

Queue ва scheduler аслида қандай ишлайди

Навбат тизими икки қисмдан иборат. Илова вазифани навбатга ёзади, масалан, маълумотлар базасидаги jobs жадвалига ёки Redis'га. Алоҳида ишлаб турган ишчи жараён, яъни queue:work, шу навбатни кузатиб боради ва ҳар бир вазифани олиб бажаради. Агар ишчи жараён ишламаса, вазифалар йўқолмайди, лекин ҳеч қачон бажарилмайди ҳам. Режалаштирувчи эса бутунлай бошқача ишлайди: Laravel ўзи вақтни кузатмайди, уни ҳар дақиқада ташқаридан php artisan schedule:run буйруғи билан уйғотиш керак. Бу буйруқ қайси вазифанинг вақти келганини текширади ва фақат ўшаларни бажаради.

Амалий мисол: Тошкентдаги хусусий клиника misol.uz сайтида беморлар қабулга ёзилади. Ёзилиш пайтида тасдиқ SMS навбатга қўйилади, ҳар куни эрталаб соат 9 да эса эртанги қабул ҳақида эслатмалар юборилади. Биринчи вазифа учун доимий ишлайдиган навбат ишчиси, иккинчиси учун эса ҳар дақиқада уйғотиладиган режалаштирувчи керак. Иккаласидан бири созланмаган бўлса, беморлар хабар олмайди ва клиника буни фақат шикоятлардан кейин билади.

Навбат драйверини танлаш ва тайёрлаш

Оддий лойиҳалар учун энг қулай драйвер маълумотлар базаси, чунки у қўшимча хизмат талаб қилмайди. .env файлида QUEUE_CONNECTION=database қийматини қўйинг. Laravel 11'да jobs ва failed_jobs жадваллари стандарт миграциялар таркибида келади, эски версияларда эса уларни алоҳида буйруқ билан яратиш керак. Юклама катта бўлса ёки вазифалар сони минглаб бўлса, Redis тезроқ ишлайди, аммо уни VPS'да ўзингиз ўрнатишингиз керак бўлади.

# Laravel 10 va undan eski versiyalarda
php artisan queue:table
php artisan queue:failed-table
php artisan migrate --force

Режалаштирувчи учун битта cron қатори

Laravel 11'да режалаштирилган вазифалар routes/console.php файлида, эски версияларда эса app/Console/Kernel.php ичидаги schedule методида ёзилади. Клиника мисолида эслатмалар қуйидагича белгиланади:

use Illuminate\Support\Facades\Schedule;

Schedule::command('reminders:send')
    ->dailyAt('09:00')
    ->timezone('Asia/Tashkent');

Вақт минтақасига алоҳида эътибор беринг: сервер UTC бўйича ишлаши мумкин ва timezone кўрсатилмаса, эслатмалар беш соат кечикиб кетади. Бу вазифаларни уйғотиш учун серверда фақат битта cron қатори керак, қолган ҳамма жадвални Laravel ўзи бошқаради:

* * * * * cd /var/www/misol && php artisan schedule:run >> /dev/null 2>&1

Оддий хостингда бу қаторни ISPmanager панелидаги режалаштирувчи (cron) бўлимида қўшасиз. Муҳим жиҳат: хостингда бир нечта PHP версияси ўрнатилган бўлиши мумкин ва php буйруғи сиз кутган версияни чақирмаслиги мумкин. Бундай ҳолда тўлиқ йўлни ёзинг, масалан /opt/php82/bin/php; аниқ йўлни sayt.uz техник ёрдами орқали билиб олишингиз мумкин.

VPS'да Supervisor билан доимий ишчи

queue:work узоқ яшайдиган жараён, у хотира оқиши, сервер қайта ишга тушиши ёки кутилмаган хато туфайли тўхтаб қолиши мумкин. Supervisor айнан шундай жараёнларни кузатиб туради ва тўхтаса, дарҳол қайта ишга туширади. Ubuntu ёки Debian'да у қуйидагича ўрнатилади:

sudo apt install supervisor

Сўнг /etc/supervisor/conf.d/misol-worker.conf файлини яратинг:

[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

Бу ерда numprocs=2 иккита параллел ишчи очади, --max-time=3600 эса ҳар бир ишчини бир соатдан кейин ўзи тўхташга мажбур қилади, Supervisor уни янгидан ишга туширади. Бу хотира аста-секин тўлиб боришининг олдини олади. stopwaitsecs қиймати энг узун вазифангиздан катта бўлиши керак, акс ҳолда тўхтатиш пайтида ярим бажарилган вазифа узилиб қолади. Конфигурацияни юклаш учун қуйидаги буйруқлар ишлатилади:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start "misol-worker:*"
sudo supervisorctl status

Supervisor бўлмаган оддий хостингда нима қилиш керак

Shared хостингда одатда Supervisor ўрнатиб бўлмайди ва доимий фон жараёнларини ушлаб туриш ҳам чекланган. Бундай ҳолда навбатни режалаштирувчининг ўзи орқали қайта ишлаш мумкин: ҳар дақиқада ишчи ишга тушади, навбатдаги ҳамма вазифани бажаради ва навбат бўшагач ўзи чиқиб кетади.

Schedule::command('queue:work --stop-when-empty --max-time=50')
    ->everyMinute()
    ->withoutOverlapping();

withoutOverlapping олдинги ишчи ҳали тугамаган бўлса, янгисини очмайди, шунинг учун жараёнлар устма-уст тўпланиб қолмайди. Бу усулда вазифалар бир дақиқагача кечикиши мумкин, лекин тасдиқ хатлари ва SMS учун бу одатда сезилмайди. Агар лойиҳада видео конвертация ёки катта экспорт каби бир неча дақиқа давом этадиган вазифалар бўлса, VPS'га ўтиш тўғрироқ ечим бўлади.

Деплой, хатолик ва назорат

Навбат ишчиси илова кодини хотирага бир марта юклайди ва янги кодни ўзи кўрмайди. Шунинг учун ҳар бир деплойдан кейин қуйидаги буйруқни бажаринг, ишчилар жорий вазифани тугатиб, юмшоқ тўхтайди ва Supervisor уларни янги код билан қайта очади:

php artisan queue:restart

Уч марта уринишдан кейин ҳам бажарилмаган вазифалар failed_jobs жадвалига тушади. Уларни php artisan queue:failed билан кўриб чиқиш ва сабабини тузатгандан кейин php artisan queue:retry all билан қайта юбориш мумкин. Вақти-вақти билан storage/logs даги логларни ҳам кўздан кечиринг: SMS шлюзи жавоб бермаётгани ёки почта пароли ўзгаргани кўпинча айнан шу ерда биринчи бўлиб кўринади. Шунда клиника беморлари хабарни ўз вақтида олади, сиз эса муаммони мижозлардан олдин кўрасиз.

Ўхшаш мақолалар

🚦 "Too many connections" хатоси: сабаб ва ечим 📁 FileZilla ва WinSCP билан хостингга SFTP орқали уланиш 🗄️ ISPmanager'да маълумотлар базаси ва фойдаланувчи яратиш 🔤 utf8mb4: эмоджи ва ўзбек ҳарфлари бузилмаслиги учун MySQL кодировкаси
🌐 Тил
🇺🇿 O'zbek 🇺🇿 Ўзбек ✓ 🇷🇺 Русский 🇬🇧 English