Kako korak za korakom začasno ustaviti in nadzorovati čakalne vrste v Laravelu

Zadnja posodobitev: December 5 2025
  • Laravel ponuja enoten API za čakalne vrste z več gonilniki (baza podatkov, Redis, SQS…) in ločitvijo med povezavami in logičnimi čakalnimi vrstami.
  • Opravila omogočajo prenos zahtevnih nalog v ozadje, s podporo za serializacijo modelov, vmesno programsko opremo, enkratna opravila, šifriranje, pakete in nize.
  • Delavce upravljamo z ukazi queue:work, Supervisor in ukazi, kot sta queue:pause/queue:continue, ki nadzorujejo ponovne poskuse, časovne omejitve in prioritete.
  • Obstaja celoten ekosistem za napake, spremljanje in testiranje (failed_jobs, queue:retry, queue:monitor, Queue::fake), zaradi česar so čakalne vrste zanesljive v produkciji.

Upravljanje čakalnih vrst v Laravelu

Delo s čakalnimi vrstami v Laravelu je skoraj obvezno pri vsakem resnem projektu: pošiljanje e-pošte, obdelava datotek CSV, ustvarjanje PDF-jev, spreminjanje velikosti slik, klicanje zunanjih API-jev ... Če se vse to naredi v glavni zahtevi HTTP, spletno mesto postane počasno, prikaže se 500 napak in uporabnik na koncu obupano strmi v prazen zaslon.

Dobra novica je, da Laravel ponuja zmogljivo in prilagodljivo infrastrukturo čakalnih vrst , ki vam omogoča, da težka opravila prenesete na procese v ozadju, jih upravljate po prioriteti, jih združujete v serije, jih spremljate, jih ponovno poskušate izvajati, ko ne uspejo, in celo začasno zaustavite procese zaradi vzdrževanja. Oglejmo si podrobneje (in ničesar ne izpustimo), kako kar najbolje izkoristiti ta proces, vključno s tem, kako ga začasno ustaviti, nadaljevati in nadzorovati njegovo delovanje v produkciji.

Osnovni pojmi: povezave, čakalne vrste in gonilniki

V Laravelu morate preden karkoli začasno ustavite, razumeti razliko med povezave čakalnih vrst in same čakalne vrste. V config/queue.php imaš matriko connections kjer definirate vsak zaledni sistem: baza podatkov, redis, beanstalkd, sqs, sinhronizacija, null, preklop ob okvari, rabbitmq (če ga dodate) itd.

Vsaka povezava ima lahko več logične čakalne vrste (imena kot default, emails, high, low, importsAtribut queue Vsaka povezava označuje, katera je privzeta čakalna vrsta, v katero bodo šla opravila, če ni določeno nič drugega. onQueue()Na ta način lahko naredite stvari, kot so:

  • Hitra čakalna vrsta za e-pošto ali kratke transakcije.
  • Še ena nizka prioriteta za dolga opravila, kot so obdelava videoposnetkov ali obsežnih poročil.
  • Čakalne vrste, segmentirane po vrsti naloge: imports, notificaciones, reportes, Itd

Ko zaženete delavca z php artisan queue:workPrivzeto posluša čakalno vrsto, določeno kot privzeto na izbrani povezavi. Če želite določiti prioritete, lahko posredujete več čakalnih vrst, ločenih z vejicami:

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

Na ta način delavec najprej obdela sporočila z visoko prioriteto , nato z default in šele nato z low , kar je ključnega pomena, ko je sistem naložen in ne želite, da 30-minutno poročilo blokira e-poštna sporočila z visoko prioriteto.

Gonilniki čakalnih vrst in predpogoji

Laravel ponuja enoten API za več gonilnikov čakalnih vrst , vendar ima vsak svoje specifične funkcije in odvisnosti. Izbira pravega gonilnika je ključnega pomena, preden se pogovorimo o zaustavitvi delavcev.

Zbirka podatkov o gonilnikih

Voznik Baza podatkov Shrani opravila v tabelo SQL (običajno jobsEnostavno ga je nastaviti in je idealen za majhne projekte ali razvojna okolja, kjer se ne želite ukvarjati z Redisom ali SQS.

Osnovni koraki:

  • Ustvari migracijo: php artisan queue:table (ali v novejših različicah je na voljo kot create_jobs_table privzeto).
  • Zaženi migracije: php artisan migrate.
  • Konfiguriraj QUEUE_CONNECTION=baza podatkov v .env in potrdite v config/queue.php da 'default' => env('QUEUE_CONNECTION','database').

Je dovolj priročen in robusten, vendar lahko zaradi številnih čakalnih vrst in velike količine prometa postane ozko grlo , saj vse poteka skozi isto relacijsko bazo podatkov.

Gonilnik Redis

Gonilnik Redis je standardni gonilnik v produkciji. Je hiter, podpira napredne funkcije (zaklepanje, omejevanje hitrosti, atomske ključavnice, Horizon itd.) in se zelo dobro skalira.

Pomembne točke:

  • Konfigurirati morate povezavo Redis v config/database.php.
  • Možnosti serializer y compression iz Redisa Niso združljivi z gonilnikom čakalne vrste.
  • Če uporabljate Redis grozdImena čakalnih vrst morajo imeti oznako hash, na primer {default}tako da vsi ključi v tej čakalni vrsti padejo v isto režo.
  • Možnost block_for Delavcu omogoča, da se med nekaj sekundami čaka na opravila blokira, namesto da bi neprekinjeno anketiral: prihrani procesor in zmanjša poizvedbe do strežnika Redis.

Na primer:

'redis' => ,

Če postavite blok_za = 0Delavec ostane blokiran za nedoločen čas, dokler ni na voljo delovno mesto, kar je treba upoštevati, če želite, da se hitro odzove na signale, kot so SIGTERM ali ukaze za začasno ustavitev.

Drugi gonilniki: SQS, Beanstalkd, null, preklop na rezervni sistem…

Poleg podatkovnih baz in redisa Laravel podpira tudi druge sisteme :

  • Amazon SQSUpravljane čakalne vrste na AWS s podporo za FIFOSkupine sporočil, odstranjevanje podvojenih sporočil in napredne nastavitve vidnosti. Zahteva SDK. aws/aws-sdk-php.
  • Fižolov stebelZelo hitro in enostavno, z uporabo paketa pda/pheanstalk.
  • sinhronizacijo: opravlja naloge takoj v istem procesu. Uporabno pri razvoju ali testiranju, v produkciji pa je praktično tako, kot da čakalnih vrst sploh ne bi uporabljali.
  • null: Zavrže opravila takoj, ko so "odposlana". Uporablja se za popolno onemogočanje sistema čakalnih vrst.
  • napak pri preklopuTo vam omogoča konfiguriranje več povezav in če primarna odpove, Laravel poskuša premakniti opravilo na naslednjo na seznamu. Idealno za okolja, kjer visoka dostopnost je kritičen.
  Electron JS: Vse, kar morate vedeti

Na ravni začasne zaustavitve in nadaljevanja delavcev je logika praktično enaka ne glede na gonilnik, ker se upravlja iz ukazov Artisan in razreda Worker , ne iz zaledja čakalne vrste.

Ustvarjanje delovnih mest in serializacija modelov

Un Job V Laravelu je to preprosto razred, ki zajema nalogo, ki se izvede v čakalni vrsti. Običajno je generiran z Artisanom in shranjen v app/Jobs.

Če ga želite ustvariti:

php artisan make:job ProcessPodcast

Ustvarjeni razred izvaja ShouldQueue in običajno uporablja lastnosti Dispatchable, InteractsWithQueue, Queueable y SerializesModelsSrce je v metodi handle()kar delavec stori, ko delo prispe.

Posebej zmogljiva funkcija je samodejna serializacija modelov Eloquent . Če v konstruktorju opravila sprejmete model, Laravel ne doda celotnega objekta v čakalno vrsto, temveč le njegov identifikator. Ko je opravilo obdelano, rekonstruira model iz baze podatkov z naloženimi relacijami.

Tipičen primer (v psevdokodnem zapisu, da se izognemo dobesednemu ponavljanju):

  • Graditelj prejme Podcast $podcast.
  • Lastnost SerializesModels Odgovoren je za shranjevanje ID-ja.
  • En handle(AudioProcessor $processor) Vi opravite težko delo (na primer obdelavo zvoka).

Če ne želite, da so relacije v modelu serializirane (da koristni tovor ni ogromen), lahko uporabite $model->withoutRelations() ali v PHP 8 atribut # na nepremičnini, ki jo oglašuje graditelj.

Vbrizgavanje odvisnosti v metodi ročaja

Druga prednost je, da lahko vbrizgaj storitve neposredno v metodo ročaja (kot da bi bil krmilnik), ker Laravel uporablja tudi vsebnik storitev v opravilih. Na primer, lahko zahtevate AudioProcessorHTTP odjemalci, repozitoriji itd., ogrodje pa poskrbi za njihovo reševanje.

Če potrebujete izjemno natančen nadzor nad tako imenovanim handlelahko uporabite Container::bindMethod() pri ponudniku storitev in sami definirajte logiko vbrizgavanja, vendar v večini primerov ni treba toliko zapletati stvari.

Vmesna programska oprema za opravila

Tako kot imajo poti vmesno programsko opremo, imajo lahko tudi opravila specifična vmesna programska oprema ki se izvajajo pred in po opravilu. To močno zmanjša ponavljajočo se kodo v metodah handle() in je še posebej uporaben za:

  • Omejitev hitrosti z Redisom.
  • izogniti prekriva del, ki se dotikajo istega vira.
  • Redne izjeme za nestabilne API-je.
  • Preskakovanje opravil pod določenimi pogoji (Skip vmesna programska oprema).

Vmesna programska oprema je običajno nameščena v app/Jobs/Middleware in so vrnjeni iz metode middleware() Iz Joba. Konceptualni primer:

public function middleware(): array { return ;

Posebne vrste opravil: edinstvena, šifrirana in zaklenjena

Laravel vam omogoča, da označite določena opravila kot edinstven da se zagotovi, da nobena dva enaka primerka nista hkrati v čakalni vrsti. To se doseže z implementacijo vmesnika ShouldBeUnique o ShouldBeUniqueUntilProcessingin podpira opredelitev ključa uniqueId() in čas uniqueFor.

To je idealno za stvari, kot so:

  • Preračunaj indeks iskanja izdelka: samo enkrat na izdelek dokler ne konča.
  • Sinhronizacije z zunanjimi storitvami, ki ne dovoljujejo sočasnih zahtev za isti vir.

Spodaj Laravel uporablja atomska ključavnica predpomnilnika (Redis, memcached, baza podatkov itd.). Gonilnik predpomnilnika za to zaklepanje lahko izberete tudi z uniqueVia().

Poleg tega je tu še vmesnik ShouldBeEncrypted, s čimer označite, da je celotno opravilo Vnesite kodo, preden se vpišete v čakalno vrstoZelo uporabno pri posredovanju občutljivih podatkov, ko ne želite, da potujejo v obliki navadnega besedila prek Redisa, SQS ali baze podatkov.

Pošiljanje, odlašanje in izvajanje opravil v različnih načinih

Ko je vaše delo definirano, ga zaženete z Job::dispatch() od krmilnikov, poslušalcev dogodkov, ukazov Artisan ali celo zaključkov. Parametri, ki jih posredujete dispatch Gredo neposredno k graditelju Joba.

Zanimive variacije:

  • dispatchIf() y dispatchUnless() da pošiljko pogojujejo v eni vrstici.
  • delay() tako da opravila ni mogoče obdelati do določenega datuma/ure.
  • dispatchAfterResponse() o afterResponse() en dispatch() Zaprtja, ki odložijo izvajanje, dokler ni poslan odgovor HTTP, vendar znotraj istega PHP procesa.
  • dispatchSync() za sinhrono izvajanje opravila (brez prehajanja skozi čakalno vrsto), vendar s ponovno uporabo istega razreda.
  • Posebne povezave, kot npr. deferred o background izvesti po odgovoru, v istem procesu ali v novem PHP procesu.

Končno lahko določite povezavo in čakalno vrsto z verižnimi metodami onConnection() y onQueue(), bodisi pri odpremi bodisi v graditelju opravil.

Natančen nadzor: ponovni poskusi, ustavitev, časovne omejitve in obravnavanje napak

Velik del dela s čakalnimi vrstami v Laravelu je odločanje o tem , kolikokrat naj se naloga ponovi , koliko časa naj se čaka med poskusi in kdaj naj se šteje za neuspeh.

  Kaj je front-end razvijalec in kaj počne?

Opciones na voljo:

  • --tries en queue:work nastaviti največje število poskusov za vsa opravila tega delavca (razen če opravilo ne definira svojega) $tries o tries()).
  • $tries ali metoda tries() v razredu Job za nadzor posameznih Jobov.
  • retryUntil() reči: »poskusi znova, kot želiš, do takrat, po tem pa neuspeh.« Če sovpada z tries, ukaz retryUntil.
  • $maxExceptions prekiniti, ko je težava posledica ponavljajočih se neobravnanih izjem.
  • $timeout o --timeout da označi, koliko sekund lahko opravilo teče, preden delavec ubije podrejeni proces.
  • $failOnTimeout označiti opravilo kot neuspešno v primeru časovne omejitve.
  • $backoff metoda backoff() za določitev časa čakanja med ponovnimi poskusi, tudi pri eksponentnih vrednostih.

Če opravilo vrže nezaznano izjemo, bo Laravel ... spusti nazaj v rep dokler se ne izčrpajo konfigurirani poskusi. To lahko ročno nadzorujete z release($segundos) o fail($exception) ko želite namerno označiti opravilo kot neuspešno.

Neuspešna opravila, tabela failed_jobs in obrezovanje

Ko Job izčrpa vse svoje poskuse, ga začnejo imeti za neuspešno delo in Laravel ga vstavi v tabelo failed_jobs (ali v DynamoDB, če ga tako konfigurirate). Ta tabela shranjuje UUID, povezavo, čakalno vrsto, koristni tovor opravila in izjemo, ki je bila vržena.

Uporabni ukazi:

  • php artisan queue:failed da naštejemo neuspešne.
  • php artisan queue:retry <id|all> da jih poskusim znova.
  • php artisan queue:forget <id> da enega izbrišete.
  • php artisan queue:flush za brisanje vseh (z možnostjo za ure v novejših različicah).
  • php artisan queue:prune-failed --hours=48 za samodejno brisanje starih zapisov.

V opravilih lahko definirate metodo failed(Throwable $exception) Za dodatno čiščenje: obvestite uporabnika, razveljavite delna dejanja, zapišite specializirane dnevnike itd. Upoštevajte, da se za klic ustvari nov primerek opravila failed()Zato se ne zanašajte na spremembe nepremičnin, narejene v handle().

Združevanje opravil: serije opravil in njihovo združevanje z nizi

Ko morate zagnati na stotine ali tisoče povezanih opravil (na primer uvoziti ogromno datoteko CSV v kosih, obdelati datoteke v paketih, očistiti podatke itd.), je priporočljivo uporabiti Laravelovo funkcionalnost paketnega obdelave .

Osnovni tok:

  • ustvari tabelo job_batches z php artisan queue:batches-table && php artisan migrate.
  • Označi opravila, ki bodo del paketov, z lastnostjo Batchable.
  • Uporabite Bus::batch() za pošiljanje niza opravil s povratnimi klici then, catch y finally.
  • Dostop do serije iz vsakega opravila z $this->batch() in preverite, ali je preklicano.
  • Možnost dodajanja več opravil v tekočo serijo z $this->batch()->add().

Serije se odlično integrirajo z verigami : verige lahko imate znotraj serije ali serije kot elemente večje verige. To je še posebej uporabno, kadar želite, da več verig teče "vzporedno" in sproži nekaj, ko so vse dokončane.

Izvajanje delavcev, prioritete in razporeditev

Vsa čarovnija čakalnih vrst se zgodi, ker imate enega ali več delavcev zagon ukaza queue:work (o queue:listen(čeprav je slednji manj učinkovit). Ti procesi so dolgotrajni demoni, ki poslušajo svoje čakalne vrste.

Ključne možnosti queue:work:

  • Povezava: php artisan queue:work redis, queue:work database, Itd
  • Colas: --queue=high,default,low dati prednost.
  • -enajst: obdela eno samo opravilo in se zaključi.
  • –max-jobs: obdela X opravil in se zaključi (za občasen ponovni zagon delavcev in sprostitev pomnilnika).
  • –maksimalni čas: obdeluje se N sekund in nato konča.
  • –spanec: sekunde čakanja, ko ni na voljo nobenih opravil.
  • –ustavi-ko-je-prazno: izprazni čakalno vrsto in se čisto zapre (idealno v Docker okoljih ali enkratnih opravilih).
  • –časovna omejitev: sekunde časovne omejitve na opravilo, kot smo že omenili.
  • - sila: za obdelavo opravil, tudi če je aplikacija v vzdrževalnem načinu.

Ker so ti procesi dolgotrajni, se v produkciji skoraj vedno uporablja nadzornik procesov, kot je Supervisor (v Linuxu), za zagon X delavcev, njihov ponovni zagon v primeru sesutja in upravljanje dnevnikov. Tipičen konfiguracijski blok Supervisorja za Laravel definira:

  • ukaz s php artisan queue:work ... beton.
  • številske_procese da navedete, koliko delavcev je treba zagnati vzporedno.
  • Poti dnevnika, uporabnik, samodejni ponovni zagoni itd.

Začasna ustavitev in nadaljevanje čakalnih vrst v Laravelu

Pojdimo k tistemu, kar je pri vzdrževanju pogosto pomembno: kako začasno ustaviti delavce v čakalni vrsti, ne da bi jih nenadoma ustavili in ne da bi opravila ostala nedokončana. Laravel ponuja več mehanizmov za nadzor nad tem, nekatere novejše, nekatere klasične.

Pavza: čakalna vrsta: signali za pavzo in prekinitev

V novejših različicah Laravel dodaja posebne ukaze za začasno ustavitev in nadaljevanje izvajanja delavcev:

  • php artisan queue:pause: sistemu pove, naj preneha sprejemati nova opravila, vendar naj pusti, da se tista, ki so že v teku, dokončajo.
  • php artisan queue:continue: nadaljuje z obdelavo novih opravil tam, kjer je končala.
  Izračun faktorja inflacije variance (VIF) v jeziku C# in pri načrtovanju programske opreme

Ti ukazi delujejo tako, da pošiljajo signale delavcem prek mehanizma predpomnjenja, ki ga Laravel uporablja interno. Zato je pomembno imeti pravilno konfiguriran gonilnik predpomnilnika (memcached, redis, database, file itd.), tudi če je vaša dejanska čakalna vrsta predpomnilnika nekaj drugega.

Pomembno: Začasna ustavitev čakalne vrste ali delavca ne prekliče ali izbriše opravil, ki so že v čakalni vrsti ; le prepreči odstranitev nadaljnjih opravil iz čakalne vrste, medtem ko traja začasna ustavitev.

Anketiranje motenj in njihov vpliv na delovanje

Vsakič, ko delavec konča delo, Laravel preveri predpomnilnik za signale za ponovni zagon, premor ali nadaljevanje . To ima zanemarljive stroške, vendar obstaja. Če ste izjemno osredotočeni na zmogljivost in veste, da delavcev ne boste morali začasno ustaviti ali znova zagnati iz ukazov, lahko to anketiranje onemogočite s klicem:

Queue::withoutInterruptionPolling();

Ali celo prilagodite statične lastnosti Illuminate\Queue\Worker za onemogočanje določenih dotikov (ponovni zagon, $pavzabilnoČe pa to storite in nato poskusite uporabiti queue:pause o queue:restartdelavci Ne bodo izvedeliGre za oblikovalsko odločitev, ki jo je treba skrbno pretehtati.

Ročna začasna ustavitev z Supervisorjem ali Dockerjem

Poleg Laravelovih lastnih ukazov se v produkcijskih okoljih procesi pogosto posredno "zaustavijo":

  • Zaustavitev programa v Supervisorju (supervisorctl stop laravel-worker:*), kar ubije ali ustavi delavce.
  • Uporaba –ustavi-ko-je-prazno v uvajanjih, da delavci dokončajo tisto, kar je v čakalni vrsti, in se nato zaustavijo.
  • V Dockerju, če pustimo, da se kontejner obdeluje z --stop-when-empty in potem se izklopi.

Razlika z queue:pause S popolno zaustavitvijo procesov boste ustavili obdelavo opravil, dokler se delavci ne zaženejo znova. notranji premor Procese lahko shranite v pomnilniku in čakate na ukaz continueTo je uporabno za hitre uvedbe ali kratka vzdrževalna obdobja.

Transakcije baze podatkov in after_commit

Klasična napaka: pošiljanje opravil znotraj transakcij baze podatkov . Če niste previdni, lahko delavec izvede opravilo, preden je potrjena vrednost (commit), in model ali podatki, ki jih pričakujete, morda še niso v bazi podatkov.

Da bi se izognili temu plesu, imate dve možnosti:

  • Vključite 'after_commit' => true v konfiguraciji povezave čakalne vrste. Tako se vsako opravilo, odposlano znotraj transakcije, interno odloži, dokler ni potrjeno.
  • Uporabite metode za posamezna opravila afterCommit() o beforeCommit() pri pošiljanju, da se vedenje vsili le v določenih opravilih.

Če se transakcija razveljavi, se opravila, odposlana med njo, zavržejo, ne da bi sploh vstopila v čakalno vrsto, kar je običajno zaželeno za ohranjanje doslednosti.

Spremljanje, čiščenje čakalnih vrst in testiranje

Ko so čakalne vrste enkrat zagnane in delujejo, ni dovolj, da preprosto zavržete opravila in pozabite nanje; morate spremljati in preizkušati, kako se vse obnaša.

Uporabna orodja in ukazi:

  • queue:clear izprazniti določeno čakalno vrsto (SQS, Redis, baza podatkov).
  • queue:monitor za spremljanje števila opravil v določenih čakalnih vrstah in sprožitev dogodka QueueBusy če presežejo določen prag.
  • Dogodki za delo kot Queue::before, Queue::after, Queue::looping y Queue::failing za priklop logike po meri (dnevniki, metrike, povrnitve itd.).
  • Ponaredki v testiranju uporabo Queue::fake() y Bus::fake() preveriti, ali so bila opravila, nizi ali paketi poslani, ne da bi se dejansko izvedli.

V testih lahko navedete stvari, kot so »to opravilo je bilo v čakalni vrsti X-krat« , »veriga s temi opravili je bila odposlana v tem vrstnem redu« ali »nobeno določeno opravilo ni bilo v čakalni vrsti«, kar zagotavlja veliko varnosti v kompleksnih tokovih.

S celotnim ekosistemom – gonilniki, kot sta Redis ali SQS, dobro zasnovanimi opravili, vmesno programsko opremo za natančno nastavitev, paketi, verigami, konfiguracijo ponovnih poskusov, delavci, ki jih upravlja nadzornik, in ukazi, kot so queue:pause y queue:continue— Laravel vam omogoča, da obvladate obdelavo v ozadju do milimetra natančno, od tipičnega pošiljanja e-pošte do porazdeljenih arhitektur čakalnih vrst z možnostjo preklopa v primeru okvare, kar zagotavlja, da se vaša aplikacija še naprej hitro odziva na ravni HTTP, medtem ko se spodaj opravlja težko delo, ne da bi pri tem blokirala uporabnika.

Laravel Framework
Povezani članek:
Zmogljivo ogrodje Laravel