Ako krok za krokom pozastaviť a ovládať fronty v Laraveli

Posledná aktualizácia: 5 decembra 2025
  • Laravel ponúka jednotné API pre fronty s viacerými ovládačmi (databáza, Redis, SQS…) a oddelením pripojení a logických frontov.
  • Úlohy umožňujú presunúť náročné úlohy na pozadie s podporou serializácie modelov, middlewaru, jednorazových úloh, šifrovania, dávok a reťazcov.
  • Pracovníci sú spravovaní pomocou queue:work, Supervisor a príkazov ako queue:pause/queue:continue, ktoré riadia opakované pokusy, časové limity a priority.
  • Existuje kompletný ekosystém pre zlyhania, monitorovanie a testovanie (failed_jobs, queue:retry, queue:monitor, Queue::fake), vďaka ktorému sú fronty v produkčnom prostredí spoľahlivé.

Správa frontov v Laraveli

Práca s frontami v Laraveli je takmer nevyhnutná v každom serióznom projekte: odosielanie e-mailov, spracovanie súborov CSV, generovanie PDF, zmena veľkosti obrázkov, volanie externých API… Ak sa toto všetko robí v hlavnej HTTP požiadavke, webová stránka sa spomalí, zobrazí sa 500 chýb a používateľ nakoniec zúfalo hľadí na prázdnu obrazovku.

Dobrou správou je, že Laravel ponúka výkonnú a flexibilnú infraštruktúru pre radenie , ktorá vám umožňuje delegovať ťažkú ​​prácu na procesy na pozadí, spravovať ich podľa priority, zoskupovať ich do dávok, monitorovať ich, opakovať ich v prípade zlyhania a dokonca dočasne pozastaviť procesy kvôli údržbe. Pozrime sa bližšie (a nič nevynecháme) na to, ako z toho vyťažiť maximum, vrátane toho, ako pozastaviť, obnoviť a ovládať jeho správanie v produkčnom prostredí.

Základné pojmy: pripojenia, fronty a ovládače

V Laraveli, predtým ako čokoľvek pozastavíte, musíte pochopiť rozdiel medzi pripojenia frontov a samotné fronty. V config/queue.php máš pole connections kde definujete každý backend: databáza, redis, beanstalkd, sqs, synchronizácia, null, záložné prepnutie, rabbitmq (ak ho pridáte) atď.

Každé pripojenie môže mať niekoľko logické fronty (názvy ako default, emails, high, low, importsAtribút queue Každé pripojenie označuje, ktorý je predvolený front, kam sa úlohy umiestnia, ak nie je zadaný iný. onQueue()Takto môžete robiť veci ako:

  • Rýchly rad pre e-maily alebo krátke transakcie.
  • Ďalšia nízka priorita pre dlhé úlohy, ako je spracovanie videí alebo rozsiahlych správ.
  • Fronty segmentované podľa typu úlohy: imports, notificaciones, reportes, Atď

Keď spustíte pracovníka s php artisan queue:workPredvolene počúva front zadaný ako predvolené na vybranom pripojení. Ak chcete uprednostniť, môžete zadať viacero frontov oddelených čiarkami:

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

Týmto spôsobom pracovník najprv spracuje high , potom default a až potom low , čo je kľúčové, keď je systém zaťažený a nechcete, aby 30-minútová správa blokovala e-maily s vysokou prioritou.

Ovládače frontov a predpoklady

Laravel ponúka jednotné API pre niekoľko ovládačov frontu , ale každý má svoje vlastné špecifické funkcie a závislosti. Výber správneho ovládača je kľúčový pred diskusiou o pozastavení workerov.

Databáza vodičov

Vodič databázy Ukladá úlohy do SQL tabuľky (zvyčajne jobsJeho nastavenie je jednoduché a je ideálny pre malé projekty alebo vývojové prostredia, kde sa nechcete hrať s Redisom alebo SQS.

Základné kroky:

  • Vygenerujte migráciu: php artisan queue:table (alebo v novších verziách sa dodáva ako create_jobs_table predvolené).
  • Spustiť migrácie: php artisan migrate.
  • konfigurácia QUEUE_CONNECTION=databáza v .env a potvrďte v config/queue.php že 'default' => env('QUEUE_CONNECTION','database').

Je to pohodlné a dostatočne robustné, ale s mnohými radmi a veľkou prevádzkou sa to môže stať úzkym hrdlom , pretože všetko prechádza cez tú istú relačnú databázu.

Ovládač Redis

Ovládač Redis je štandardným pracantom v produkčnom prostredí. Je rýchly, podporuje pokročilé funkcie (zamykanie, obmedzovanie rýchlosti, atomické zámky, Horizon atď.) a veľmi dobre sa škáluje.

Dôležité body:

  • Musíte nakonfigurovať pripojenie Redis v config/database.php.
  • Možnosti serializer y compression z Redisu Nie sú kompatibilné s vodičom frontu.
  • Ak používate Klaster RedisNázvy frontov musia mať hashtag, napríklad {default}aby všetky kľúče v danom rade spadali do rovnakého slotu.
  • Možnosť block_for Umožňuje pracovníkovi blokovať sa počas čakania na úlohy niekoľko sekúnd namiesto neustáleho dotazovania: šetrí CPU a redukuje dotazy na server Redis.

Napríklad:

'redis' => ,

Ak vložíte blok_pre = 0Pracovník zostáva zablokovaný na neurčito, kým sa neuvoľní práca, čo je potrebné mať na pamäti, ak chcete, aby rýchlo reagoval na signály ako SIGTERM alebo pozastaviť príkazy.

Ďalšie ovládače: SQS, Beanstalkd, null, failover…

Okrem databáz a redis podporuje Laravel aj iné systémy :

  • Amazon SQSRady spravované spoločnosťou AWS s podporou pre FIFOSkupiny správ, deduplikácia a rozšírené nastavenia viditeľnosti. Vyžaduje sadu SDK. aws/aws-sdk-php.
  • BeanstalkdVeľmi rýchle a jednoduché, pomocou balíka pda/pheanstalk.
  • synchronizovať: vykonáva úlohy bezodkladne v tom istom procese. Užitočné pri vývoji alebo testovaní, ale v produkcii je to prakticky ako keby ste fronty vôbec nepoužívali.
  • null: Zahodí úlohy hneď po ich „odoslaní“. Používa sa na úplné vypnutie systému radenia.
  • failoverTo vám umožňuje nakonfigurovať viacero pripojení a ak to primárne zlyhá, Laravel sa pokúsi presunúť úlohu na ďalšie v zozname. Ideálne pre prostredia, kde vysoká dostupnosť je kritická.
  Electron JS: Všetko, čo potrebujete vedieť

Na úrovni pozastavovania a obnovovania workerov je logika prakticky rovnaká bez ohľadu na ovládač, pretože je riadená z príkazov Artisan a triedy Worker , nie z backendu frontu.

Vytváranie úloh a serializácia modelov

Un zamestnania V Laraveli je to jednoducho trieda, ktorá zapuzdruje úlohu, ktorá sa má vykonať vo fronte. Zvyčajne sa generuje pomocou Artisanu a ukladá sa do app/Jobs.

Postup vytvorenia:

php artisan make:job ProcessPodcast

Vygenerovaná trieda náradie ShouldQueue a zvyčajne používa vlastnosti Dispatchable, InteractsWithQueue, Queueable y SerializesModelsSrdce je v metóde handle()čo pracovník urobí, keď práca príde.

Obzvlášť silnou funkciou je automatická serializácia modelov Eloquentu . Ak v konštruktore úlohy prijmete model, Laravel nepridá do frontu celý objekt, iba jeho identifikátor. Po spracovaní úlohy rekonštruuje model z databázy s načítanými vzťahmi.

Typický príklad (v pseudokóde, aby sa predišlo doslovnému opakovaniu):

  • Staviteľ dostane Podcast $podcast.
  • Táto vlastnosť SerializesModels Je zodpovedný za uloženie ID.
  • En handle(AudioProcessor $processor) Vy robíte ťažkú ​​prácu (napríklad spracovanie zvuku).

Ak nechcete, aby boli vzťahy v modeli serializované (aby užitočné zaťaženie nebolo obrovské), môžete použiť $model->withoutRelations() alebo v PHP 8 atribút # na nehnuteľnosti propagovanej staviteľom.

Vkladanie závislostí do metódy handle

Ďalšou výhodou je, že môžete vložiť služby priamo do metódy handle (ako keby to bol kontrolér), pretože Laravel tiež používa kontajner služieb v úlohách. Napríklad môžete požiadať o AudioProcessorHTTP klienti, repozitáre atď. a framework sa postará o ich riešenie.

Ak potrebujete ultrajemnú kontrolu nad tým, čo sa nazýva handlemôžete použiť Container::bindMethod() u poskytovateľa služieb a definovať logiku vstrekovania sami, ale vo väčšine prípadov nie je potrebné veci až tak komplikovať.

Middleware úloh

Rovnako ako trasy majú middleware, aj úlohy môžu mať špecifický middleware ktoré sa spúšťajú pred a po úlohe. To výrazne znižuje počet opakujúcich sa kódov v metódach handle() a je obzvlášť užitočný pre:

  • Obmedzenie rýchlosti s Redisom.
  • vyhnúť sa sa prekrýva diel, ktoré sa dotýkajú toho istého zdroja.
  • Pravidelné výnimky pre nestabilné API.
  • Preskakovanie úloh za určitých podmienok (Skip middleware).

Middleware sa zvyčajne umiestňuje do app/Jobs/Middleware a sú vrátené z metódy middleware() Z knihy Jób. Koncepčný príklad:

public function middleware(): array { return ;

Špeciálne typy úloh: jedinečné, šifrované a uzamknuté

Laravel vám umožňuje označiť určité úlohy ako jedinečný aby sa zabezpečilo, že žiadne dve identické inštancie nebudú nikdy zaradené do frontu súčasne. Toto sa dosiahne implementáciou rozhrania ShouldBeUnique o ShouldBeUniqueUntilProcessinga podporuje definovanie kľúča uniqueId() a čas uniqueFor.

Toto je ideálne na veci ako:

  • Prepočítajte index vyhľadávania produktu: iba raz na produkt kým sa to neskončí.
  • Synchronizácie s externými službami, ktoré neumožňujú súbežné požiadavky na ten istý zdroj.

V spodnej časti Laravel používa atómový zámok vyrovnávacej pamäte (Redis, memcached, databáza atď.). Ovládač vyrovnávacej pamäte pre daný zámok si môžete vybrať aj pomocou uniqueVia().

Okrem toho je tu rozhranie ShouldBeEncrypted, čím označíte, že úloha je kompletná Zadajte svoj kód pred vstupom do frontuVeľmi užitočné pri prenose citlivých údajov, keď nechcete, aby sa prenášali ako obyčajný text cez Redis, SQS alebo databázu.

Odosielanie, odkladanie a vykonávanie úloh v rôznych režimoch

Keď je vaša úloha definovaná, spustíte ju pomocou Job::dispatch() z ovládačov, poslucháčov udalostí, príkazov Artisan alebo dokonca uzávierok. Parametre, ktoré odovzdávate dispatch Idú priamo k staviteľovi Jóba.

Zaujímavé variácie:

  • dispatchIf() y dispatchUnless() upravovať zásielku v jednom riadku.
  • delay() takže úloha nemôže byť spracovaná až do určitého dátumu/času.
  • dispatchAfterResponse() o afterResponse() en dispatch() Uzávierky, ktoré odkladajú vykonanie, kým sa neodošle odpoveď HTTP, ale v rámci toho istého PHP procesu.
  • dispatchSync() spustiť úlohu synchrónne (bez prechodu cez front), ale s opätovným použitím tej istej triedy.
  • Špeciálne spojenia, ako napr. deferred o background vykonať po odpovedi, v tom istom procese alebo v novom PHP procese.

Nakoniec môžete zadať pripojenie a front pomocou reťazených metód onConnection() y onQueue(), či už pri odosielaní alebo v nástroji na tvorbu úloh.

Jemná kontrola: opakované pokusy, odloženie, časové limity a spracovanie chýb

Veľkou súčasťou práce s frontami v Laraveli je rozhodovanie o tom, koľkokrát sa má úloha opakovať , ako dlho sa má čakať medzi pokusmi a kedy sa má považovať za zlyhanie.

  Čo je to front-end vývojár a čo robí?

Dostupné možnosti:

  • --tries en queue:work nastaviť maximálny počet pokusov pre všetky úlohy daného pracovníka (pokiaľ úloha nedefinuje svoj vlastný) $tries o tries()).
  • $tries alebo metóda tries() v triede Job pre riadenie jednotlivých úloh.
  • retryUntil() povedať: „Skúšaj to znova, koľko chceš, až doteraz, potom je to neúspech.“ Ak sa to zhoduje s tries, príkaz retryUntil.
  • $maxExceptions prerušiť, keď je problém spôsobený opakovanými neošetrenými výnimkami.
  • $timeout o --timeout na označenie, koľko sekúnd môže úloha bežať predtým, ako pracovník ukončí podradený proces.
  • $failOnTimeout označiť úlohu ako neúspešnú v prípade uplynutia časového limitu.
  • $backoff metóda backoff() definovať, ako dlho čakať medzi opakovanými pokusmi, a to aj pri exponenciálnych hodnotách.

Ak úloha vyvolá nezachytenú výnimku, Laravel... uvoľňuje sa späť do chvosta kým sa nevyčerpajú nakonfigurované pokusy. Toto môžete ovládať manuálne pomocou release($segundos) o fail($exception) keď chcete úlohu zámerne označiť ako neúspešnú.

Zlyhané úlohy, tabuľka failed_jobs a prerezávanie

Keď Jób vyčerpá svoje pokusy, začne sa o ňom uvažovať neúspešná práca a Laravel ho vloží do tabuľky failed_jobs (alebo v DynamoDB, ak to tak nakonfigurujete). Táto tabuľka uchováva UUID, pripojenie, front, dáta úlohy a vyvolanú výnimku.

Užitočné príkazy:

  • php artisan queue:failed vymenovať tie, ktoré zlyhali.
  • php artisan queue:retry <id|all> aby som ich skúsil znova.
  • php artisan queue:forget <id> vymazať jeden.
  • php artisan queue:flush odstrániť všetky (s možnosťou hodín v novších verziách).
  • php artisan queue:prune-failed --hours=48 automaticky odstrániť staré záznamy.

V časti Úlohy môžete definovať metódu failed(Throwable $exception) Pre dodatočné čistenie: upozornenie používateľa, vrátenie čiastočných akcií, zapisovanie špecializovaných protokolov atď. Upozorňujeme, že na volanie sa vytvorí nová inštancia úlohy. failed()Preto sa nespoliehajte na zmeny majetku vykonané v handle().

Dávkovanie úloh: dávky úloh a ich kombinovanie pomocou reťazcov

Keď potrebujete spustiť stovky alebo tisíce súvisiacich úloh (napríklad importovať obrovský CSV súbor po častiach, spracovávať súbory v dávkach, čistiť dáta atď.), je vhodné použiť dávkovú funkcionalitu Laravelu .

Základný tok:

  • vytvorte tabuľku job_batches s php artisan queue:batches-table && php artisan migrate.
  • Označte úlohy, ktoré budú súčasťou dávok, pomocou vlastnosti Batchable.
  • použitie Bus::batch() odoslať sadu úloh s spätnými volaniami then, catch y finally.
  • Prístup k dávke z každej úlohy pomocou $this->batch() a skontrolujte, či je zrušený.
  • Možnosť pridať ďalšie úlohy do prebiehajúcej dávky s $this->batch()->add().

Dávky sa krásne integrujú s reťazcami : reťazce môžete mať v rámci dávky alebo dávky ako prvky väčšieho reťazca. Toto je obzvlášť užitočné, keď chcete, aby viacero reťazcov bežalo „paralelne“ a spúšťalo niečo po ich dokončení.

Vykonávanie, priority a nasadenie pracovníkov

Všetko kúzlo radov sa deje, pretože máte jeden alebo viac pracovníkov spustenie príkazu queue:work (o queue:listen(hoci ten druhý je menej efektívny). Tieto procesy sú dlho bežiace démony, ktoré počúvajú svoje príslušné fronty.

Kľúčové možnosti queue:work:

  • Spojenie: php artisan queue:work redis, queue:work database, Atď
  • Fronty: --queue=high,default,low stanoviť si priority.
  • jedenásť: spracuje jednu úlohu a ukončí sa.
  • –max-jobs: spracuje X úloh a ukončí sa (aby sa periodicky reštartovali workeri a uvoľnila pamäť).
  • –maximálny čas: spracováva sa N sekúnd a potom sa ukončí.
  • –spánok: sekundy čakania, keď nie sú k dispozícii žiadne úlohy.
  • –zastaviť-keď-je-prázdno: vyprázdni front a čisto sa zatvorí (ideálne v prostrediach Docker alebo pri jednorazových úlohách).
  • –časový limit: sekundy časového limitu na úlohu, ako sme už spomenuli.
  • -force: na spracovanie úloh, aj keď je aplikácia v režime údržby.

Keďže tieto procesy bežia dlho, v produkčnom prostredí sa takmer vždy používa monitor procesov, ako napríklad Supervisor (v Linuxe), na spustenie X workerov, ich reštartovanie v prípade zlyhania a správu protokolov. Typický konfiguračný blok Supervisor pre Laravel definuje:

  • povel s php artisan queue:work ... betón.
  • numprocs aby sa určilo, koľko pracovníkov sa má spustiť paralelne.
  • Cesty protokolov, používateľ, automatické reštarty atď.

Pozastavenie a obnovenie frontov v Laraveli

Poďme sa pozrieť na to, čo je pri údržbe často dôležité: ako pozastaviť procesy vo fronte bez ich náhleho zastavenia a bez toho, aby úlohy zostali nedokončené. Laravel ponúka niekoľko mechanizmov na ovládanie tohto procesu, niektoré novšie, niektoré klasické.

Pauza: front: signály pauzy a prerušenia

V novších verziách Laravel pridáva špecifické príkazy na pozastavenie a obnovenie vykonávania workerov:

  • php artisan queue:pause: povie systému, aby prestal prijímať nové úlohy, ale nechal dokončiť tie, ktoré už prebiehajú.
  • php artisan queue:continue: obnoví spracovanie nových úloh od miesta, kde prestalo.
  Výpočet faktora inflácie rozptylu (VIF) v jazyku C# a softvérovom dizajne

Tieto príkazy fungujú tak, že odosielajú signály pracovníkom prostredníctvom mechanizmu vyrovnávacej pamäte, ktorý Laravel používa interne. Preto je dôležité mať správne nakonfigurovaný ovládač vyrovnávacej pamäte (memcached, redis, database, file atď.), aj keď vaša skutočná fronta vyrovnávacej pamäte je niečo iné.

Dôležité: Pozastavenie frontu alebo pracovníka nezruší ani neodstráni úlohy, ktoré sú už zaradené do frontu ; iba zabráni odstráneniu ďalších úloh z frontu počas trvania pozastavenia.

Prieskum prerušení a ich vplyv na výkon

Vždy, keď worker dokončí úlohu, Laravel skontroluje vyrovnávaciu pamäť, či neobsahuje signály reštartu, pozastavenia alebo pokračovania . Toto má zanedbateľné náklady, ale existuje. Ak sa mimoriadne zameriavate na výkon a viete, že nebudete musieť pozastaviť alebo reštartovať workerov z príkazov, môžete toto dotazovanie vypnúť volaním:

Queue::withoutInterruptionPolling();

Alebo dokonca upraviť statické vlastnosti Illuminate\Queue\Worker zakázať konkrétne dotyky ($reštartovateľné, $pauzovateľnéAk to však urobíte a potom sa pokúsite použiť queue:pause o queue:restartrobotníci Nezistia toJe to dizajnérske rozhodnutie, ktoré by sa malo starostlivo zvážiť.

Manuálne pozastavenie pomocou Supervisora ​​alebo Dockera

Okrem vlastných príkazov Laravelu sú v produkčných prostrediach procesy často nepriamo „pozastavené“:

  • Zastavenie programu v Supervisore (supervisorctl stop laravel-worker:*), čo zabíja alebo zastavuje pracovníkov.
  • použitím –zastaviť-keď-je-prázdno v nasadeniach, aby pracovníci dokončili to, čo je vo fronte, a potom sa vypli.
  • V Dockeri, nechať kontajner spracovať s --stop-when-empty a potom sa vypne.

Rozdiel s queue:pause Úplným zastavením procesov zastavíte spracovanie úloh, kým sa pracovníkov reštartuje. vnútorná pauza Procesy môžete uchovávať v pamäti a čakať na príkaz continueToto je užitočné pre rýchle vrátenie zmien alebo krátke obdobia údržby.

Databázové transakcie a after_commit

Klasická chyba: odosielanie úloh v rámci databázových transakcií . Ak si nedáte pozor, pracovník môže úlohu vykonať ešte pred vykonaním potvrdenia (commit) a model alebo údaje, ktoré očakávate, ešte nemusia byť v databáze.

Aby ste sa tomuto tancovaniu vyhli, máte dve možnosti:

  • Aktivovať 'after_commit' => true v konfigurácii pripojenia frontu. Preto je každá úloha odoslaná v rámci transakcie interne odložená, kým nie je potvrdená.
  • Používajte metódy pre jednotlivé úlohy afterCommit() o beforeCommit() pri odosielaní vynútiť správanie iba v konkrétnych úlohách.

Ak je transakcia obrátená, úlohy odoslané počas nej sa zahodia bez toho, aby sa dostali do frontu, čo je presne to, čo je zvyčajne žiaduce na zachovanie konzistencie.

Monitorovanie, čistenie frontu a testovanie

Keď už máte fronty naplno rozbehnuté, nestačí len zahodiť úlohy a zabudnúť na ne; mali by ste monitorovať a testovať, ako sa všetko správa.

Užitočné nástroje a príkazy:

  • queue:clear vyprázdniť konkrétny front (SQS, Redis, databáza).
  • queue:monitor monitorovať počet úloh v určitých frontoch a spúšťať udalosť QueueBusy ak prekročia určitú hranicu.
  • Pracovné udalosti ako Queue::before, Queue::after, Queue::looping y Queue::failing na pripojenie vlastnej logiky (logy, metriky, vrátenia zmien atď.).
  • Falzifikáty v testovaní použitie Queue::fake() y Bus::fake() overiť, či boli úlohy, reťazce alebo dávky odoslané bez ich skutočného vykonania.

V testoch môžete uviesť veci ako „táto úloha bola zaradená do frontu X-krát“ , „reťazec s týmito úlohami bol odoslaný v tomto poradí“ alebo „žiadna konkrétna úloha nebola zaradená do frontu“, čo poskytuje veľa bezpečnosti v zložitých tokoch.

S celým týmto ekosystémom – ovládačmi ako Redis alebo SQS, dobre navrhnutými úlohami, middlewareom na doladenie, dávkami, reťazcami, konfiguráciou opakovaných pokusov, pracovníkmi spravovanými supervízorom a príkazmi ako queue:pause y queue:continue— Laravel vám umožňuje zvládnuť spracovanie na pozadí s presnosťou na milimeter, od typického odosielania e-mailov až po architektúry distribuovaných frontov s prepínaním pri zlyhaní, čím sa zabezpečí, že vaša aplikácia bude naďalej rýchlo reagovať na vrstve HTTP, aj keď sa pod ňou vykonáva náročná práca bez blokovania používateľa.

Laravel Framework
Súvisiaci článok:
Výkonný Laravel Framework