In dit artikel gaan we de Queue API in het Laravel-webraamwerk verkennen. Hiermee kunt u tijdens de scriptuitvoering resource-intensieve taken uitstellen om de algehele eindgebruikerservaring te verbeteren. Na het introduceren van de basisterminologie, zal ik het demonstreren door een realistisch voorbeeld te implementeren.
De laadtijd van de pagina is een belangrijk aspect van elke succesvolle website en het belang hiervan mag niet over het hoofd worden gezien, omdat dit ook van invloed is op de SEO van de site en de algehele ervaring van de eindgebruiker. Vaker wel dan niet, moet u uiteindelijk webpagina's debuggen met lange laadtijd van pagina's. Natuurlijk zijn er verschillende benaderingen die u zou kunnen gebruiken om dit probleem te verhelpen.
Bij onderzoek realiseert u zich vaak dat bepaalde codeblokken een vertraging in de uitvoering van de pagina veroorzaken. Het volgende dat u kunt proberen, is het identificeren van blokken die kunnen worden uitgesteld voor verwerking en die geen echte invloed hebben op het eindresultaat van de huidige pagina. Dat zou de algehele webpagina-snelheid echt moeten verbeteren, omdat we de codeblokken hebben verwijderd die een vertraging veroorzaakten.
Vandaag gaan we een soortgelijk concept verkennen in de context van het Laravel-webraamwerk. Laravel biedt al een bruikbare ingebouwde API waarmee we de verwerking van taken kunnen uitstellen, de wachtrij-API. Zonder veel tijd te verspillen, bespreek ik de basiselementen van de Queue API.
Het basisdoel van de Queue API is om taken uit te voeren die in een wachtrij zijn toegevoegd. De wachtrij zou vervolgens kunnen behoren tot een specifieke verbinding en die verbinding kan tot een specifiek wachtrijstuurprogramma behoren dat met die verbinding zelf is geconfigureerd. Laten we even proberen te begrijpen wat ik net heb gezegd.
Op dezelfde manier zou u een ander stuurprogramma voor uw databaseverbinding hebben gebruikt, u zou ook uit een groot aantal verschillende wachtrijstuurprogramma's kunnen kiezen. De Queue API ondersteunt verschillende adapters zoals database, beanstalkd, sqs en redis.
Het wachtrijstuurprogramma is slechts een plaats die wordt gebruikt om aan wachtrij gerelateerde informatie op te slaan. Dus als u bijvoorbeeld een databasewachtrij-stuurprogramma gebruikt, wordt de nieuwe taak toegevoegd aan de taaptabel in de database. Als u daarentegen opnieuw hebt ingesteld als het standaardwachtrijstuurprogramma, wordt de taak toegevoegd aan de redis-server.
De Queue API biedt ook twee speciale wachtrij-stuurprogramma's voor testdoeleinden: synchroniseren en null. Het synchrone wachtrijstuurprogramma wordt gebruikt om een wachtrijtaak onmiddellijk uit te voeren, terwijl het nulwachtrijstuurprogramma wordt gebruikt om een taak over te slaan zodat deze helemaal niet wordt uitgevoerd.
Wanneer u de wachtrij-API voor de eerste keer configureert, moet u een standaardverbinding opgeven die moet worden gebruikt voor de standaardwachtrijverwerking. Op zijn minst zal de verbinding naar verwachting de volgende informatie opleveren:
Wanneer u een taak aan een wachtrij toevoegt, wordt deze aan de standaardwachtrij toegevoegd. In feite zou dat in de meeste gevallen goed moeten zijn, tenzij je banen hebt die een hogere prioriteit moeten krijgen boven andere banen. In dat geval zou u een wachtrij kunnen maken met de naam hoog en plaats de jobs met hogere prioriteit in die specifieke wachtrij.
Wanneer u een wachtrijwerknemer uitvoert die taken in de wachtrij verwerkt, kunt u optioneel de --wachtrij
parameter, waarmee u namen van wachtrijen kunt weergeven in de volgorde waarin ze moeten worden verwerkt. Bijvoorbeeld, als u opgeeft --wachtrij = hoog, default
, het zal eerst banen verwerken in de hoog wachtrij en zodra deze is voltooid, worden taken opgehaald in de standaardwachtrij.
Een taak in de wachtrij-API is een taak die wordt uitgesteld van de hoofduitvoerstroom. Als u bijvoorbeeld een miniatuur wilt maken wanneer de gebruiker een afbeelding vanaf de front-end uploadt, kunt u een nieuwe taak maken die de miniatuurverwerking verwerkt. Op deze manier kunt u de taak van de miniatuurbewerking uit de hoofduitvoeringsstroom uitstellen.
Dat was een basisinleiding voor de terminologie van de wachtrij-API. In het volgende gedeelte zullen we onderzoeken hoe een aangepaste wachtrijtaak kan worden gemaakt en uitgevoerd met behulp van een Laravel-wachtrijmedewerker.
Inmiddels moet u vertrouwen hebben in wachtrijjobs. In dit gedeelte gaan we een realistisch voorbeeld implementeren dat het concept van wachtrijtaken in Laravel laat zien.
Vaker wel dan niet, kom je in de situatie terecht waarin je verschillende thumbnail-versies van een door een gebruiker geuploade afbeelding moet maken. In de meeste gevallen probeert de ontwikkelaar het in realtime te verwerken, zodat er meteen verschillende versies van afbeeldingen worden gemaakt wanneer de gebruiker een afbeelding uploadt.
Het lijkt een redelijke benadering als je een paar versies gaat maken en het neemt in de eerste plaats niet te veel tijd in beslag. Aan de andere kant, als u te maken hebt met een toepassing die zware verwerking vereist en dus meer bronnen ophaalt, kan real-time verwerking resulteren in een slechte gebruikerservaring.
De voor de hand liggende optie die in de eerste plaats opduikt, is om de verwerking van de miniatuurgeneratie zo laat mogelijk uit te stellen. De eenvoudigste benadering die u in dit specifieke scenario kunt implementeren, is het instellen van een cron-taak waarmee de verwerking met regelmatige tussenpozen wordt gestart..
Een veel betere aanpak is echter om de taak uit te stellen en de taak in een wachtrij te plaatsen en de wachtrijmedewerker deze te laten verwerken wanneer hij de kans krijgt om dit te doen. In een productieomgeving is de wachtrijwerker een daemon-script dat altijd wordt uitgevoerd en taken in een wachtrij verwerkt. Het voor de hand liggende voordeel van deze aanpak is een veel betere eindgebruikerservaring en u hoeft niet te wachten op de cron-run, omdat de taak zo snel mogelijk wordt verwerkt..
Ik denk dat dat genoeg theorie is om aan de slag te gaan met een daadwerkelijke implementatie.
In ons geval gaan we het gebruiken databank
wachtrijstuurprogramma en dit vereist dat we het jobs
tabel in de database. De jobs
tabel bevat alle taken die moeten worden verwerkt in de volgende rij van de wachtrijwerknemer.
Voordat we doorgaan en het maken jobs
tabel, laten we de standaardwachtrijconfiguratie wijzigen van synchroniseren
naar databank
in de config / queue.php
het dossier.
... / * | ---------------------------------------------- ---------------------------- | Default Queue Driver | ---------------------------------------------- ---------------------------- | | Laravel's wachtrij-API ondersteunt een assortiment back-ends via een enkele | API, waarmee u gemakkelijk toegang hebt tot elke back-end met dezelfde | syntaxis voor elk. Hier kunt u het standaard wachtrijstuurprogramma instellen. | | Ondersteund: "sync", "database", "beanstalkd", "sqs", "redis", "null" | * / 'standaard' => env ('QUEUE_DRIVER', 'database'), ...
In feite biedt Laravel al een ambachtelijk commando dat ons helpt om het jobs
tafel. Voer de volgende opdracht uit in de hoofdmap van uw Laravel-toepassing en maak de benodigde databasemigratie die de jobs
tafel.
$ php artisan-wachtrij: tabel
Het migratiebestand dat is gegenereerd op databank / migraties / YYYY_MM_DD_HHMMSS_create_jobs_table.php
zou er als volgt uit moeten zien:
bigIncrements ( 'id'); $ Tafel-> string ( 'wachtrij'); $ Tafel-> longtext ( 'payload'); $ Tafel-> unsignedTinyInteger ( 'pogingen'); $ Tafel-> unsignedInteger ( 'reserved_at') -> vernietigbaar (); $ Tafel-> unsignedInteger ( 'available_at'); $ Tafel-> unsignedInteger ( 'created_at'); $ table-> index (['queue', 'reserved_at']); ); / ** * Keer de migraties terug. * * @return void * / public function down () Schema :: dropIfExists ('jobs');
Laten we vervolgens de trekken
commando zodat het daadwerkelijk de jobs
tabel in een database.
php artisan migreren
Dat is het voor zover als het jobs
migratie betreft.
Laten we vervolgens de Beeld
model dat zal worden gebruikt om afbeeldingen te beheren die door de eindgebruiker zijn geüpload. Het afbeeldingsmodel vereist ook een bijbehorende databasetabel, dus we gebruiken de --trekken
optie tijdens het maken van de Beeld
model-.
php artisan make: model Afbeelding - migratie
Het bovenstaande commando zou het moeten maken Beeld
modelklasse en een bijbehorende databasemigratie.
De Beeld
modelklasse zou er als volgt uit moeten zien:
En het database-migratiebestand zou moeten worden aangemaakt bij
databank / migraties / YYYY_MM_DD_HHMMSS_create_images_table.php
. We willen ook het originele pad van de afbeelding opslaan die door de eindgebruiker is geüpload. Laten we de code van deBeeld
databasemigratiebestand om er als volgt uit te zien.verhogingen ( 'id'); $ Tafel-> timestamps (); $ Tafel-> string ( 'org_path'); ); / ** * Keer de migraties terug. * * @return void * / public function down () Schema :: dropIfExists ('images');Zoals u kunt zien, hebben we het
$ Tafel-> string ( 'org_path')
kolom om het pad van de originele afbeelding op te slaan. Vervolgens moet u gewoon detrekken
opdracht om die tabel daadwerkelijk in de database te maken.$ php artisan migrerenEn dat is het voor zover als het
Beeld
model betreft.Laten we vervolgens een echte wachtrijtaak maken die verantwoordelijk is voor het verwerken van afbeeldingsminiaturen. Voor de miniatuurverwerking gebruiken we een zeer populaire beeldverwerkingsbibliotheek - Intervention Image.
Om de Intervention Image-bibliotheek te installeren, moet u de volgende opdracht uitvoeren in de hoofdmap van uw toepassing.
$ php composer.phar vereist een interventie / afbeeldingNu is het tijd om het te maken
job
klasse, en we zullen een ambachtelijk commando gebruiken om dat te doen.$ php artisan make: job ProcessImageThumbnailsDat zou het moeten maken
job
class template atapp / Banen / ProcessImageThumbnails.php
. Laten we de inhoud van dat bestand vervangen door het volgende.afbeelding = $ afbeelding; / ** * Voer de taak uit. * * @return void * / public function handle () // toegang tot het model in de wachtrij voor verwerking $ image = $ this-> image; $ full_image_path = public_path ($ image-> org_path); $ resized_image_path = public_path ('thumbs'. DIRECTORY_SEPARATOR. $ image-> org_path); // maak afbeeldingduimen van de originele afbeelding $ img = \ Afbeelding :: make ($ full_image_path) -> formaat wijzigen (300, 200); $ Img-> save ($ resized_image_path);Wanneer de wachtrijmedewerker begint met het verwerken van een taak, zoekt deze naar de
handvat
methode. Dus het is hethandvat
methode die de hoofdlogica van uw taak bevat.In ons geval moeten we een miniatuur maken van een afbeelding die door de gebruiker is geüpload. De code van de
handvat
methode is vrij eenvoudig - we halen een afbeelding uit deImageModel
model en maak een miniatuur met behulp van de Intervention Image-bibliotheek. Natuurlijk moeten we het overeenkomstige doorgevenBeeld
model wanneer we onze baan verzenden, en we zullen het zo meteen zien.Om onze nieuw gecreëerde taak te testen, maken we een eenvoudig uploadformulier waarmee de gebruiker een afbeelding kan uploaden. Natuurlijk zullen we niet meteen beeldminiaturen maken; we stellen die taak uit zodat deze kan worden verwerkt door de wachtrijmedewerker.
Laten we een controllerbestand maken op
app / Http / Controllers / ImageController.php
zoals hieronder getoond.validate ($ request, ['demo_image' => 'required | image | mimes: jpeg, png, jpg, gif, svg | max: 2048',]); $ image = $ request-> file ('demo_image'); $ input ['demo_image'] = time (). '.'. $ image-> getClientOriginalExtension (); $ destinationPath = public_path ('/ images'); $ image-> move ($ destinationPath, $ input ['demo_image']); // make db entry van die afbeelding $ image = new Image; $ image-> org_path = 'afbeeldingen'. DIRECTORY_SEPARATOR. $ Ingang [ 'demo_image']; $ Beeld-> save (); // uitstellen van de verwerking van de afbeeldingsminiaturen ProcessImageThumbnails :: dispatch ($ image); return Redirect :: to ('image / index') -> with ('message', 'Afbeelding succesvol geüpload!');Laten we een gekoppeld weergavebestand maken op
resources / views / upload_form.blade.php
.Laravel @if (Route :: has ('login'))@if (Auth :: check ()) Home @else Inloggen Registreren @endif@stop alsDemo-uploadformulier
@if ($ errors-> any ())@endif @if (sessie ('bericht'))@foreach ($ errors-> all () als $ fout)
- $ fout
@endforeachsession ('message')@stop alsLaten we tot slot routes toevoegen voor de
inhoudsopgave
enuploaden
acties in deroutes / web.php
het dossier.Route :: get ('image / index', 'ImageController @ index'); Route :: post ('afbeelding / upload', 'ImageController @ upload');In de
ImageController
controller, deinhoudsopgave
methode wordt gebruikt om een uploadformulier te renderen.openbare functie-index (verzoek $ aanvraag) return view ('upload_form');Wanneer de gebruiker een formulier verzendt, wordt de
uploaden
methode wordt aangeroepen.public function upload (Request $ request) // upload afbeelding $ this-> validate ($ request, ['demo_image' => 'vereist | afbeelding | mimespelers: jpeg, png, jpg, gif, svg | max: 2048', ]); $ image = $ request-> file ('demo_image'); $ input ['demo_image'] = time (). '.'. $ image-> getClientOriginalExtension (); $ destinationPath = public_path ('/ images'); $ image-> move ($ destinationPath, $ input ['demo_image']); // make db entry van die afbeelding $ image = new Image; $ image-> org_path = 'afbeeldingen'. DIRECTORY_SEPARATOR. $ Ingang [ 'demo_image']; $ Beeld-> save (); // uitstellen van de verwerking van de afbeeldingsminiaturen ProcessImageThumbnails :: dispatch ($ image); return Redirect :: to ('image / index') -> with ('message', 'Afbeelding succesvol geüpload!');Aan het begin van de
uploaden
methode, zult u de gebruikelijke bestandsuploadcode opmerken die het geüploade bestand naar depubliek / images
directory. Vervolgens voegen we een databaserecord in met behulp van deApp / Beeld
model-.Ten slotte gebruiken we de
ProcessImageThumbnails
taak om de miniatuurverwerkingstaak uit te stellen. Het is belangrijk op te merken dat het deverzending
methode die wordt gebruikt om een taak uit te stellen. Aan het eind wordt de gebruiker omgeleid naar de uploadpagina met een succesbericht.Op dit moment wordt de taak toegevoegd aan de
jobs
tabel voor verwerking. Laten we het bevestigen door de volgende query uit te voeren.mysql> selecteer * FROM lvl_jobs; | 1 | standaard | "Selecteer": "App \\ Jobs \\ ProcessImageThumbnails", "job": "Verlicht \\ Queue \\ CallQueuedHandler @ noemen", "maxTries": null, "time-out": null, "data": "commandonaam ":" App \\ Jobs \\ ProcessImageThumbnails " "opdracht": "O: 31: \" App \\ Jobs \\ ProcessImageThumbnails \ ": 5: s: 8: \" \ u0000 * \ u0000image \"; O: 45: \ "Illuminate \\ Contracten \\ Database \\ ModelIdentifier \": 2: s: 5: \ "class \"; s: 9: \ "App \\ Image \"; s: 2: \ "id \"; i: 2; s: 6: \ "\ u0000 * \ u0000job \" N; s: 10: \ "verbinding \" N; s: 5: \ "file \", N; s: 5: \ "delay \"; N; " | 0 | NULL | 1510219099 | 1510219099 |Je moet je afvragen, wat is er dan nodig om een baan te verwerken? Maak je geen zorgen, dat is wat we in het volgende gedeelte gaan bespreken.
Wachtrijwerknemer
Het is de taak van de Laravel-wachtrijmedewerker om taken te verwerken die in de wachtrij staan voor verwerking. In feite is er een ambachtelijk commando dat ons helpt om het wachtrijwerkproces te starten.
$ php artisan-wachtrij: werkZodra u die opdracht uitvoert, worden wachtende taken verwerkt. In ons geval zou het het moeten verwerken
ProcessImageThumbnails
taak die in de wachtrij is geplaatst toen de gebruiker een afbeelding eerder uploadde.$ php artisan queue: work [YYYY-MM-DD HHMMSS] Verwerking: App \ Jobs \ ProcessImageThumbnails [JJJJ-MM-DD HHMMSS] Verwerkt: App \ Jobs \ ProcessImageThumbnailsHet zou je zijn opgevallen dat wanneer je een wachtrijmedewerker opstart, deze blijft werken tot je hem handmatig doodt of de terminal sluit. In feite wacht het tot de volgende taak wordt verwerkt. Zodra er een nieuwe taak in de wachtrij staat, wordt deze meteen verwerkt als de wachtrijmedewerker actief is.
We kunnen het natuurlijk niet zo houden, dus we moeten een manier vinden waarop de wachtrijmedewerker permanent op de achtergrond kan worden uitgevoerd.
Tot onze redding zijn er verschillende tools voor procesbeheer waar je uit kunt kiezen. Om een paar te noemen, hier is een lijst:
U moet een hulpmiddel kiezen waarmee u vertrouwd bent om de Laravel-wachtrijmedewerker te beheren. Kortom, we willen er zeker van zijn dat de wachtrijmedewerker voor onbepaalde tijd moet werken, zodat hij onmiddellijk wachtrijen verwerkt..
Dus dat is de Queue API tot uw beschikking. U kunt het bij uw dagelijkse ontwikkeling gebruiken om tijdrovende taken uit te stellen om de eindgebruikerservaring te verbeteren.
In dit artikel hebben we de wachtrij-API besproken in Laravel, wat erg handig is als je de verwerking van resource-intensieve taken wilt uitstellen.
We zijn begonnen met een basisinleiding van de Queue API, die een bespreking van verbindingen, wachtrijen en taken omvatte. In de tweede helft van het artikel hebben we een aangepaste wachtrijjob gemaakt die aantoonde hoe je de Queue API in de echte wereld kon gebruiken.
Voor degenen onder u die net zijn begonnen met Laravel of die op zoek zijn om uw kennis, site of applicatie uit te breiden met uitbreidingen, hebben we een aantal dingen die u kunt bestuderen in Envato Market.
Voel je vrij om het onderstaande feedbackformulier te gebruiken om je vragen en suggesties te plaatsen.