În acest articol, vom explora API-ul Queue în cadrul web Laravel. Vă permite să amânați sarcinile cu resurse intensive în timpul execuției scriptului pentru a îmbunătăți experiența generală a utilizatorilor finali. După introducerea terminologiei de bază, o voi demonstra prin implementarea unui exemplu din lumea reală.
Timpul de încărcare a paginilor este un aspect important al oricărui site web de succes și nu trebuie să trecem cu vederea importanța acestui lucru, deoarece afectează SEO-ul site-ului și experiența generală a utilizatorului final. De cele mai multe ori, veți ajunge să debugați pagini web cu timpi de încărcare lungi. Desigur, există diferite abordări pe care le-ați putea folosi pentru a remedia această problemă.
La investigație, vă dați seama adesea că există anumite blocuri de coduri care provoacă o întârziere în execuția paginii. Următorul lucru pe care îl puteți încerca este identificarea blocurilor care pot fi amânate pentru procesare și care nu au un impact real asupra rezultatului final al paginii curente. Acest lucru ar trebui să îmbunătățească într-adevăr viteza generală a paginii web, deoarece am eliminat blocurile de cod care au cauzat o întârziere.
Astăzi, vom explora un concept similar în contextul cadrului web Laravel. De fapt, Laravel oferă deja un utilitar API util, care ne permite să amânam procesarea sarcinilor - API-ul Queue. Fără a pierde o mare parte din timpul tău, voi continua și voi discuta elementele de bază ale API Queue.
Scopul principal al API-ului Queue este de a executa lucrări care sunt adăugate într-o coadă. În continuare, coada de așteptare ar putea aparține unei anumite conexiuni și această conexiune ar putea aparține unui driver specific de coadă configurat cu acea conexiune în sine. Să încercăm pe scurt ceea ce am spus.
În același mod în care ați fi folosit un driver diferit pentru conexiunea la baza de date, puteți alege de asemenea dintr-o varietate de drivere de coadă diferite. Aplicația Queue API acceptă adaptoare diferite, cum ar fi baza de date, beanstalkd, sqs și redis.
Șoferul de coadă este doar un loc care este utilizat pentru a stoca informații legate de coadă. Deci, dacă utilizați un driver de coadă de bază de date, de exemplu, noua lucrare va fi adăugată în tabela de activități din baza de date. Pe de altă parte, dacă ați configurat redis ca driver de coadă implicit, jobul va fi adăugat la serverul redis.
Aplicația Queue API oferă, de asemenea, două drivere speciale de coadă pentru scopuri de testare - sincronizare și null. Șoferul de coadă de sincronizare este utilizat pentru a executa imediat o lucrare de coadă, în timp ce driverul de coadă nulă este utilizat pentru a sări peste o lucrare, astfel încât să nu fie executată deloc.
Când configurați pentru prima dată API-ul Queue, trebuie să specificați o conexiune prestabilită care ar trebui utilizată pentru procesarea implicită a coadajelor. Cel puțin este de așteptat ca conexiunea să furnizeze următoarele informații:
Când adăugați orice lucrare într-o coadă, aceasta va fi adăugată în coada de așteptare. De fapt, acest lucru ar trebui să fie bine în majoritatea cazurilor, cu excepția cazului în care aveți locuri de muncă cărora trebuie să li se acorde o prioritate mai mare față de alte locuri de muncă. În acest caz, puteți crea o coadă denumită înalt și plasați joburile cu prioritate mai mare în acea coadă specială.
Când rulați un lucrător de coadă care procesează lucrări în așteptare, puteți trece opțional --coadă
parametru, care vă permite să listați numele de coadă în ordinea în care trebuie procesate. De exemplu, dacă specificați --coadă = mare, implicit
, va procesa mai întâi locuri de muncă în înalt coada și, odată finalizată, prelucrează lucrările în coada de așteptare.
O lucrare în API Queue este o sarcină care este amânată din fluxul de execuție principal. De exemplu, dacă doriți să creați o miniatură atunci când utilizatorul încarcă o imagine din front-end, puteți crea o nouă operație care să gestioneze procesarea miniaturilor. În acest fel, puteți să amânați sarcina de procesare a miniaturilor din fluxul principal de execuție.
Aceasta a fost o introducere de bază a terminologiei API Queue. Din următoarea secțiune, vom explora cum să creați o lucrare de coadă personalizată și să o executați utilizând un lucrător de coadă Laravel.
Până acum, ar trebui să vă simțiți încrezători în ocuparea coadă de așteptare. Din această secțiune, vom implementa un exemplu din lumea reală care demonstrează conceptul de locuri de muncă pentru coadă în Laravel.
De cele mai multe ori, veți ajunge în situația în care trebuie să creați diferite versiuni de miniaturi ale unei imagini încărcate de un utilizator. În cele mai multe cazuri, dezvoltatorul încearcă să o proceseze în timp real, astfel încât diferite versiuni ale imaginilor să fie create imediat când utilizatorul încarcă o imagine.
Se pare că este o abordare rezonabilă dacă veți crea câteva versiuni și nu va dura prea mult timp în primul rând. Pe de altă parte, dacă aveți de-a face cu o aplicație care necesită procesare intensă și, prin urmare, mănâncă mai multe resurse, prelucrarea în timp real ar putea ajunge într-o experiență nefavorabilă a utilizatorului.
Opțiunea evidentă care apare în mintea ta în primul rând este să amâne procesarea generației de miniaturi cât mai târziu posibil. Cea mai simplă abordare pe care ați putea-o implementa în acest scenariu specific este de a seta un job cron care declanșează procesarea la intervale regulate și ar trebui să fiți bine.
O abordare mult mai bună, pe de altă parte, este de a amâna și împingeți sarcina într-o coadă de așteptare și lăsați-o pe lucrătorul de coadă să o proceseze atunci când are șansa să o facă. Într-un mediu de producție, lucrătorul pentru coadă este un script de daemon care rulează întotdeauna și procesează sarcini într-o coadă. Beneficiul evident al acestei abordări este o experiență mult mai bună pentru utilizatorul final și nu trebuie să așteptați executarea programului cron deoarece lucrarea va fi procesată cât mai repede posibil.
Cred că este suficient teoria pentru a începe cu o implementare reală.
În cazul nostru, vom folosi Bază de date
driver de coadă, și ne cere să creăm locuri de munca
tabel în baza de date. locuri de munca
tabela deține toate lucrările care trebuie procesate în următoarea lucrare de coadă de așteptare.
Înainte de a începe și a crea locuri de munca
tabel, să modificăm configurația coadă de așteptare de la sincronizați
la Bază de date
în config / queue.php
fişier.
... / * | ---------------------------------------------- ---------------------------- | Implicit Driver Queue | ---------------------------------------------- ---------------------------- | | Extensia API a lui Laravel sprijină un sortiment de back-enduri printr-un singur | API, oferindu-vă un acces convenabil la fiecare back-end utilizând același | sintaxa pentru fiecare dintre ele. Aici puteți seta driverul de coadă prestabilit. | | Susținute: "sincronizare", "bază de date", "beanstalkd", "sqs", "redis", "null" | * / 'default' => env ('QUEUE_DRIVER', 'baza de date'), ...
De fapt, Laravel oferă deja o comandă artizanală care ne ajută să creăm locuri de munca
masa. Rulați următoarea comandă în rădăcina aplicației Laravel și ar trebui să creeze migrarea necesară a bazei de date care creează locuri de munca
masa.
$ php artisan queue: tabel
Fișierul de migrare generat la Bază de date / migrări / YYYY_MM_DD_HHMMSS_create_jobs_table.php
ar trebui să arate astfel:
bigIncrements ( 'id'); $ Table-> string ( 'coadă'); $ Table-> longText ( 'sarcină utilă'); $ Table-> unsignedTinyInteger ( 'tentative'); $ Table-> unsignedInteger ( 'reserved_at') -> poate fi nulă (); $ Table-> unsignedInteger ( 'available_at'); $ Table-> unsignedInteger ( 'created_at'); $ table-> index (['queue', 'reserved_at']); ); / ** * Reveniți la migrații. * * @return void * / funcția publică în jos () Schema :: dropIfExists ('jobs');
În continuare, hai să conducem migra
comandă astfel încât să creeze efectiv locuri de munca
tabel într-o bază de date.
php artizan migrează
Asta e în ceea ce privește locuri de munca
migrației.
Apoi, să creați Imagine
model care va fi folosit pentru a gestiona imaginile încărcate de utilizatorul final. Modelul de imagine necesită, de asemenea, o tabelă de bază de date asociată, așa că vom folosi --migra
în timpul creării Imagine
model.
php artisan face: imagine model - migrare
Comanda de mai sus ar trebui să creeze Imagine
clasa de model și migrarea bazei de date asociate.
Imagine
clasa de modele ar trebui să arate astfel:
Fișierul de migrare a bazei de date ar trebui să fie creat la
Bază de date / migrări / YYYY_MM_DD_HHMMSS_create_images_table.php
. De asemenea, dorim să stocăm calea originală a imaginii încărcate de utilizatorul final. Să revizuim codulImagine
fișierul de migrare a bazei de date să arate după cum urmează.incremente ( 'id'); $ Table-> timestamps (); $ Table-> string ( 'org_path'); ); / ** * Reveniți la migrații. * * @return void * / funcția publică în jos () Schema :: dropIfExists ('images');După cum puteți vedea, am adăugat
$ Table-> string ( 'org_path')
pentru a stoca calea imaginii originale. Apoi, trebuie doar să rulațimigra
comandă pentru a crea acel tabel în baza de date.$ php artizan migreazăȘi asta e în ceea ce privește
Imagine
model.Apoi, să creăm o lucrare de așteptare care este responsabilă pentru procesarea miniaturilor imaginilor. Pentru procesarea miniaturilor, vom folosi o bibliotecă foarte populară de procesare a imaginilor - Intervenție.
Pentru a instala biblioteca Image Intervention, continuați și rulați următoarea comandă la radacina aplicației.
$ php composer.phar necesită intervenție / imagineAcum, este timpul să creați
Loc de munca
și vom folosi o comandă artizanală pentru a face asta.$ php artisan face: job ProcessImageThumbnailsAceasta ar trebui să creeze
Loc de munca
clasă laapp / Locuri de munca / ProcessImageThumbnails.php
. Să înlocuim conținutul acelui fișier cu următoarele.image = $ image; / ** * Executați lucrarea. * * @return void * / mâner funcția publică () // accesați modelul în coadă pentru procesarea imaginii $ image = $ this->; $ full_image_path = cale_publică ($ image-> cale_organică); $ resized_image_path = calea publica ('thumbs'; DIRECTORY_SEPARATOR; $ image-> org_path); // crea imaginea degetului mare din imaginea originală $ img = \ Image :: make ($ full_image_path) -> redimensionare (300, 200); $ Img-> Salvați ($ resized_image_path);Când lucrătorul de coadă începe să proceseze orice lucrare, acesta caută
mâner
metodă. Deci este vorba demâner
metodă care ține logica principală a locului de muncă.În cazul nostru, trebuie să creați o miniatură a unei imagini încărcată de utilizator. Codul codului
mâner
metoda este destul de simplă - extragem o imagine dinImageModel
mode și creați o miniatură utilizând biblioteca de imagini Intervenție. Bineînțeles, trebuie să trecem pe cea corespunzătoareImagine
atunci când ne expediem slujba și o vom vedea într-o clipă.Pentru a testa jobul nou creat, vom crea un formular simplu de încărcare care permite utilizatorului să încarce o imagine. Desigur, nu vom crea miniaturi de imagini imediat; vom amâna sarcina astfel încât aceasta să poată fi procesată de lucrătorul în așteptare.
Să creăm un fișier de controler la
app / HTTP / Controllers / ImageController.php
așa cum se arată mai jos.validare ($ request, ['demo_image' => 'necesar | imagine | mimes: jpeg, png, jpg, gif, svg | max: 2048',]); fișierul $ image = $ request-> ('demo_image'); $ input ['demo_image'] = timp (). '.'. $ image-> getClientOriginalExtension (); $ destinationPath = calea publica ('/ images'); $ image-> mutare ($ destinationPath, $ input ['demo_image']); // face intrarea db a acelei imagini $ image = imagine nouă; $ image-> org_path = 'imagini'. DIRECTORY_SEPARATOR. intrare $ [ 'demo_image']; $ Image-> Salvare (); // amânarea procesării miniaturilor de imagini ProcessImageThumbnails :: dispatch ($ image); returnează Redirecționare :: la ('imagine / index') -> cu ('mesaj', 'Imaginea încărcată cu succes!');Să creăm un fișier de vizualizare asociat la
Resurse / opinii / upload_form.blade.php
.Laravel @if (Route :: are ('login'))@if (Auth :: check ()) Pagina principală @ notă Conectare Înregistrare @endif@endifFormularul de încărcare demo
@if ($ erori-> orice ())@endif @if (sesiune ("mesaj"))@foreach ($ errors-> all () ca eroare $)
- $ error
@endforeachsesiune ('mesaj')@endifÎn cele din urmă, să adăugăm rute pentru
index
șiîncărcați
acțiuni înrute / web.php
fişier.Route :: get ('imagine / index', 'ImageController @ index'); Traseu :: post ('image / upload', 'ImageController @ upload');În
ImageController
controler,index
metoda este folosită pentru a face un formular de încărcare.indexul funcției publice (Cerere $ request) retur ("upload_form");Atunci când utilizatorul prezintă un formular,
încărcați
metoda este invocată.($ request, ['demo_image' => 'necesar | imagine | mime: jpeg, png, jpg, gif, svg | max: 2048'; ]); fișierul $ image = $ request-> ('demo_image'); $ input ['demo_image'] = timp (). '.'. $ image-> getClientOriginalExtension (); $ destinationPath = calea publica ('/ images'); $ image-> mutare ($ destinationPath, $ input ['demo_image']); // face intrarea db a acelei imagini $ image = imagine nouă; $ image-> org_path = 'imagini'. DIRECTORY_SEPARATOR. intrare $ [ 'demo_image']; $ Image-> Salvare (); // amânarea procesării miniaturilor de imagini ProcessImageThumbnails :: dispatch ($ image); returnează Redirecționare :: la ('imagine / index') -> cu ('mesaj', 'Imaginea încărcată cu succes!');La începutul
încărcați
, veți observa codul obișnuit de încărcare a fișierului care va muta fișierul încărcat în/ imagini publice
director. Apoi, inserăm o înregistrare bazei de date folosindApp / Imagine
model.În cele din urmă, folosim
ProcessImageThumbnails
pentru a amâna sarcina de procesare a miniaturilor. Este important să rețineți că este vorba despreexpediere
metodă care este folosită pentru a amâna o sarcină. În final, utilizatorul este redirecționat către pagina de încărcare cu un mesaj de succes.În acest moment, postul este adăugat la
locuri de munca
tabel pentru prelucrare. Să o confirmăm prin emiterea următoarei interogări.mysql> select * FROM lvl_jobs; | 1 | implicit | "DISPLAYNAME": "App \\ \\ Jobs ProcessImageThumbnails", "locuri de muncă": "Luminarea \\ Coadă \\ CallQueuedHandler @ apel", "maxTries": "timeout": null, "date" nulă: "numele comenzii ":" App \\ \\ ProcessImageThumbnails Jobs " "comandă": "O: 31: \" App \\ Jobs \\ ProcessImageThumbnails \ ": 5: s: 8: \" \ u0000 * \ u0000image \"; O: 45: \ "Illuminate \\ Contracte \\ Database \\ ModelIdentifier \": 2: s: 5: \ "clasa \"; s: 9: \ "App \\ Image \"; s: 2: \ "id \"; i: 2; s: 6: \ "\ u0000 * \ u0000job \"; N; s: 10: \ "conexiune \"; N; s: 5: \ "coadă \"; N; s: 5: \ "întârziere \"; N; " | 0 | NULL | 1510219099 | 1510219099 |Trebuie să vă întrebați ce trebuie să faceți pentru a-ți procesa un loc de muncă atunci? Nu vă faceți griji - asta vom discuta în secțiunea următoare.
Lucrătoare de coadă
Funcția lucrătorului de coadă Laravel este de a procesa locurile de muncă care sunt în așteptare pentru procesare. De fapt, există o comandă artizanală care ne ajută să începem procesul de lucru pentru coadă.
$ php artizan queue: workDe îndată ce executați comanda respectivă, procesează lucrările în așteptare. În cazul nostru, ar trebui să proceseze
ProcessImageThumbnails
o lucrare care a fost în așteptare atunci când utilizatorul a încărcat o imagine mai devreme.$ php artisan queue: work [YYYY-MM-DD HHMMSS] Procesare: App \ Jobs \ ProcessImageThumbnails [YYYY-MM-DD HHMMSS]Ați fi observat că atunci când începeți un lucrător de coadă, acesta continuă să funcționeze până când îl omorâți manual sau închideți terminalul. De fapt, așteaptă ca următorul loc de muncă să fie procesat. De îndată ce există o nouă lucrare în coadă, aceasta va fi procesată imediat dacă lucrătorul de coadă se execută.
Desigur, nu putem să o păstrăm așa, așa că trebuie să găsim o cale pentru lucrătorul care se află în coada de așteptare să ruleze permanent în fundal.
Pentru salvarea noastră, există mai multe instrumente de gestionare a proceselor de acolo pe care le puteți alege. Pentru a numi câteva, iată o listă:
Ar trebui să alegeți un instrument cu care vă convine să gestionați lucrătorul de coadă Laravel. Practic, vrem să ne asigurăm că lucrătorul de așteptare ar trebui să funcționeze pe o perioadă nedeterminată, astfel încât să proceseze imediat joburile în așteptare.
Deci, asta e API-ul Queue la dispoziția ta. Puteți să-l utilizați în dezvoltarea de zi cu zi pentru a amâna sarcinile consumatoare de timp pentru a îmbunătăți experiența utilizatorului final.
În acest articol am discutat despre API-ul Queue în Laravel, care este cu adevărat util dacă doriți să amânați procesarea sarcinilor consumatoare de resurse.
Am început cu o introducere de bază la API-ul Queue, care a implicat o discuție despre conexiuni, cozi și locuri de muncă. În a doua jumătate a articolului, am creat o lucrare de coadă particularizată, care a demonstrat modul în care ați putea utiliza API-ul Queue în lumea reală.
Pentru cei care sunteți fie doar începători cu Laravel, fie căutați să vă extindeți cunoștințele, site-ul sau aplicația cu extensii, avem o varietate de lucruri pe care le puteți studia în piața Envato.
Simțiți-vă liber să utilizați formularul de feedback de mai jos pentru a posta întrebările și sugestiile.