Verschieben von Aufgaben in Laravel mithilfe von Warteschlangen

In diesem Artikel werden wir die Warteschlangen-API im Laravel-Webframework untersuchen. Sie können ressourcenintensive Aufgaben während der Skriptausführung verschieben, um die Benutzererfahrung insgesamt zu verbessern. Nachdem ich die grundlegende Terminologie eingeführt habe, werde ich sie anhand eines realen Beispiels demonstrieren.

Die Ladezeit der Seite ist ein wichtiger Aspekt jeder erfolgreichen Website, und man sollte die Wichtigkeit dieser Tatsache nicht übersehen, da sie die SEO der Website und die allgemeine Endbenutzererfahrung beeinflusst. In den meisten Fällen müssen Sie Webseiten mit langen Seitenladezeiten debuggen. Natürlich gibt es verschiedene Ansätze, um dieses Problem zu beheben.

Bei der Untersuchung stellen Sie oft fest, dass bestimmte Codeblöcke eine Verzögerung bei der Seitenausführung verursachen. Als nächstes könnten Sie versuchen, Blöcke zu identifizieren, die für die Verarbeitung zurückgestellt werden können und die das Endergebnis der aktuellen Seite nicht wirklich beeinflussen. Dies sollte die Geschwindigkeit der gesamten Webseite wirklich verbessern, da Codeblöcke, die eine Verzögerung verursachen, beseitigt wurden.

Heute werden wir ein ähnliches Konzept im Zusammenhang mit dem Laravel-Web-Framework untersuchen. In der Tat bietet Laravel bereits eine nützliche integrierte API, mit der wir die Verarbeitung von Tasks, der Queue-API, verzögern können. Ohne viel Zeit zu verlieren, werde ich die grundlegenden Elemente der Warteschlangen-API besprechen.

Treiber, Verbindungen, Warteschlangen und Jobs

Der grundlegende Zweck der Warteschlangen-API besteht darin, in einer Warteschlange hinzugefügte Jobs auszuführen. Als Nächstes könnte die Warteschlange zu einer bestimmten Verbindung gehören, und diese Verbindung kann zu einem bestimmten Warteschlangentreiber gehören, der für diese Verbindung selbst konfiguriert ist. Versuchen wir kurz zu verstehen, was ich gerade gesagt habe.

Warteschlangentreiber

Auf dieselbe Weise, als hätten Sie einen anderen Treiber für Ihre Datenbankverbindung verwendet, können Sie auch aus verschiedenen Warteschlangentreibern auswählen. Die Warteschlangen-API unterstützt verschiedene Adapter wie Datenbank, Beanstalkd, SQL und Redis.

Der Warteschlangentreiber ist nur ein Ort, an dem Warteschlangeninformationen gespeichert werden. Wenn Sie beispielsweise einen Datenbankwarteschlangentreiber verwenden, wird der neue Job in der Jobtabelle der Datenbank hinzugefügt. Wenn Sie dagegen redis als Standardwarteschlangentreiber konfiguriert haben, wird der Job zum redis-Server hinzugefügt.

Die Warteschlangen-API stellt außerdem zwei spezielle Warteschlangentreiber für Testzwecke zur Verfügung, die die Synchronisierung und den Nullwert betreffen. Der Sync-Warteschlangentreiber wird verwendet, um einen Warteschlangenjob sofort auszuführen, während der Nullwarteschlangentreiber zum Überspringen eines Jobs verwendet wird, sodass er überhaupt nicht ausgeführt wird.

Verbindungen

Wenn Sie die Warteschlangen-API zum ersten Mal konfigurieren, müssen Sie eine Standardverbindung angeben, die für die Standardwarteschlangenverarbeitung verwendet werden soll. Zumindest wird erwartet, dass die Verbindung die folgenden Informationen bereitstellt:

  • Der zu verwendende Warteschlangentreiber
  • die spezifischen Konfigurationswerte des Warteschlangentreibers
  • Der Standardwarteschlangenname, in dem der Job hinzugefügt wird

Warteschlangen

Wenn Sie einen Job zu einer Warteschlange hinzufügen, wird er zur Standardwarteschlange hinzugefügt. In der Tat sollte dies in den meisten Fällen in Ordnung sein, es sei denn, Sie haben Jobs, denen höhere Priorität eingeräumt werden muss als andere Jobs. In diesem Fall können Sie eine Warteschlange mit dem Namen erstellen hoch und platzieren Sie die Jobs mit höherer Priorität in dieser bestimmten Warteschlange.

Wenn Sie einen Warteschlangen-Worker ausführen, der Aufträge in der Warteschlange verarbeitet, können Sie optional den Job übergeben --Warteschlange Parameter, mit dem Sie die Warteschlangennamen in der Reihenfolge auflisten können, in der sie verarbeitet werden müssen. Zum Beispiel, wenn Sie angeben --Warteschlange = Hoch, Standard, Es werden zuerst Jobs im bearbeitet hoch In der Warteschlange werden die Aufträge in der Standardwarteschlange abgerufen.

Arbeitsplätze

Ein Job in der Warteschlangen-API ist eine Aufgabe, die vom Hauptausführungsablauf verschoben wird. Wenn Sie beispielsweise eine Miniaturansicht erstellen möchten, wenn der Benutzer ein Bild vom Front-End hochlädt, können Sie einen neuen Job erstellen, der die Miniaturbildverarbeitung verarbeitet. Auf diese Weise könnten Sie die Aufgabe der Miniaturbildverarbeitung vom Hauptausführungsablauf verschieben.

Dies war eine grundlegende Einführung in die Queue-API-Terminologie. Ab dem nächsten Abschnitt erfahren Sie, wie Sie einen benutzerdefinierten Warteschlangenjob erstellen und mithilfe eines Laravel-Warteschlangenarbeiters ausführen können.

Erstellen Sie Ihren ersten Warteschlangenjob

Inzwischen sollten Sie sich bei Warteschlangenjobs sicher fühlen. Von diesem Abschnitt an werden wir ein reales Beispiel implementieren, das das Konzept von Warteschlangenjobs in Laravel demonstriert.

In den meisten Fällen geraten Sie in die Situation, in der Sie verschiedene Miniaturversionen eines Bildes erstellen müssen, das von einem Benutzer hochgeladen wurde. In den meisten Fällen versucht der Entwickler, es in Echtzeit zu verarbeiten, so dass verschiedene Versionen von Bildern sofort erstellt werden, wenn der Benutzer ein Bild hochlädt.

Es scheint ein vernünftiger Ansatz zu sein, wenn Sie ein paar Versionen erstellen möchten, und es dauert überhaupt nicht viel Zeit. Wenn Sie dagegen mit einer Anwendung zu tun haben, die eine umfangreiche Verarbeitung erfordert und somit mehr Ressourcen verbraucht, kann die Echtzeitverarbeitung zu einer schlechten Benutzererfahrung führen.

Die naheliegendste Option, die in Ihrem Kopf auftaucht, besteht darin, die Verarbeitung der Miniaturansicht so spät wie möglich zu verschieben. Der einfachste Ansatz, den Sie in diesem speziellen Szenario implementieren könnten, besteht darin, einen Cron-Job festzulegen, der die Verarbeitung in regelmäßigen Abständen auslöst.

Ein viel besserer Ansatz ist es dagegen, die Aufgabe zu verschieben und in eine Warteschlange zu verschieben, damit der Warteschlangenarbeiter sie verarbeiten kann, wenn er die Gelegenheit dazu hat. In einer Produktionsumgebung ist der Warteschlangen-Worker ein Daemon-Skript, das immer ausgeführt wird und Aufgaben in einer Warteschlange verarbeitet. Der offensichtliche Vorteil dieses Ansatzes ist eine viel bessere Endbenutzererfahrung, und Sie müssen nicht auf den Cron-Lauf warten, da der Job so schnell wie möglich verarbeitet wird.

Ich denke, das ist genug Theorie, um mit einer tatsächlichen Implementierung zu beginnen.

In unserem Fall verwenden wir die Datenbank Warteschlangentreiber, und es erfordert, dass wir das erstellen Arbeitsplätze Tabelle in der Datenbank. Das Arbeitsplätze Tabelle enthält alle Jobs, die beim nächsten Warteschlangenarbeitslauf verarbeitet werden müssen.

Bevor wir loslegen und das erstellen Arbeitsplätze Lassen Sie uns die Standard-Warteschlangenkonfiguration von ändern Sync zu Datenbank in dem config / queue.php Datei.

… / * | ---------------------------------------------- ---------------------------- | Standard-Warteschlangentreiber | ---------------------------------------------- ---------------------------- | | Die Warteschlangen-API von Laravel unterstützt eine Reihe von Backends über eine einzige | API, mit der Sie bequem auf jedes Backend zugreifen können, indem Sie dasselbe | verwenden Syntax für jeden. Hier können Sie den Standard-Warteschlangentreiber festlegen. | | Unterstützt: "sync", "database", "beanstalkd", "sqs", "redis", "null" | * / 'default' => env ('QUEUE_DRIVER', 'Datenbank'),… 

In der Tat bietet Laravel bereits einen handwerklichen Befehl, der uns beim Erstellen der Arbeitsplätze Tabelle. Führen Sie den folgenden Befehl im Stammverzeichnis Ihrer Laravel-Anwendung aus, und es sollte die erforderliche Datenbankmigration erstellt werden, die die Datenbank erstellt Arbeitsplätze Tabelle.

$ php Handwerker-Warteschlange: Tabelle

Die Migrationsdatei, die unter generiert wird Datenbank / Migrationen / JJJJ_MM_DD_HHMMSS_create_jobs_table.php sollte so aussehen:

bigIncrements ('id'); $ table-> string ('queue'); $ table-> longText ('payload'); $ table-> unsignedTinyInteger ('Versuche'); $ table-> unsignedInteger ('reserved_at') -> nullable (); $ table-> unsignedInteger ('available_at'); $ table-> unsignedInteger ('created_at'); $ table-> index (['queue', 'reserved_at']); );  / ** * Kehren Sie die Migrationen um. * * @return void * / public function down () Schema :: dropIfExists ('jobs');  

Lassen Sie uns als Nächstes das ausführen Wandern Befehl, damit es tatsächlich das erstellt Arbeitsplätze Tabelle in einer Datenbank.

PHP Handwerker migrieren

Das ist es soweit Arbeitsplätze Migration ist betroffen.

Als nächstes erstellen wir die Bild Modell, das zur Verwaltung der vom Endbenutzer hochgeladenen Bilder verwendet wird. Das Image-Modell erfordert auch eine zugehörige Datenbanktabelle, daher verwenden wir die --Wandern Option beim Erstellen der Bild Modell-.

PHP Handwerker machen: Modell Image --migration

Der obige Befehl sollte das erstellen Bild Modellklasse und eine zugehörige Datenbankmigration ebenfalls.

Das Bild Die Modellklasse sollte so aussehen:

Die Datenbankmigrationsdatei sollte unter erstellt werden Datenbank / Migrationen / JJJJ_MM_DD_HHMMSS_create_images_table.php. Wir möchten auch den ursprünglichen Pfad des vom Endbenutzer hochgeladenen Bildes speichern. Lassen Sie uns den Code von überarbeiten Bild Datenbankmigrationsdatei sollte wie folgt aussehen.

Inkremente ('id'); $ table-> timestamps (); $ table-> string ('org_path'); );  / ** * Kehren Sie die Migrationen um. * * @return void * / public function down () Schema :: dropIfExists ('images'); 

Wie Sie sehen können, haben wir das hinzugefügt $ table-> string ('org_path') Spalte, um den Pfad des Originalbilds zu speichern. Als nächstes müssen Sie nur das ausführen Wandern Befehl, um diese Tabelle tatsächlich in der Datenbank zu erstellen.

$ php Handwerker migrieren

Und das ist es soweit Bild Modell ist betroffen.

Als Nächstes erstellen wir einen tatsächlichen Warteschlangenjob, der für die Verarbeitung von Miniaturbildern verantwortlich ist. Für die Miniaturbildverarbeitung verwenden wir eine sehr beliebte Bildbearbeitungsbibliothek - Interventionsbild.

Um die Interventions-Image-Bibliothek zu installieren, führen Sie den folgenden Befehl im Stammverzeichnis Ihrer Anwendung aus.

$ php composer.phar erfordert Intervention / Image

Nun ist es an der Zeit, das zu erstellen Job Klasse, und wir werden einen handwerklichen Befehl verwenden, um das zu tun.

$ php Handwerker make: job ProcessImageThumbnails

Das sollte das schaffen Job Klassenvorlage bei app / Jobs / ProcessImageThumbnails.php. Lassen Sie uns den Inhalt dieser Datei durch Folgendes ersetzen.

image = $ image;  / ** * Führen Sie den Job aus. * * @return void * / public function handle () // Zugriff auf das Modell in der Warteschlange für die Verarbeitung von $ image = $ this-> image; $ full_image_path = public_path ($ image-> org_path); $ resized_image_path = public_path ('thumbs'. DIRECTORY_SEPARATOR. $ image-> org_path); // Image-Thumbs aus dem ursprünglichen Image erstellen $ img = \ Image :: make ($ full_image_path) -> resize (300, 200); $ img-> save ($ resized_image_path); 

Wenn der Warteschlangenarbeiter mit der Verarbeitung eines Jobs beginnt, sucht er nach dem Griff Methode. So ist es das Griff Methode, die die Hauptlogik Ihres Jobs enthält.

In unserem Fall müssen wir eine Miniaturansicht eines vom Benutzer hochgeladenen Bildes erstellen. Der Code des Griff Methode ist ziemlich unkompliziert - wir rufen ein Bild von der ImageModel modellieren und mit der Interventionsbild-Bibliothek ein Miniaturbild erstellen. Natürlich müssen wir das entsprechende bestehen Bild Modell, wenn wir unseren Job abschicken, und wir werden es gleich sehen.

Um unseren neu erstellten Job zu testen, erstellen wir ein einfaches Upload-Formular, mit dem der Benutzer ein Bild hochladen kann. Natürlich erstellen wir keine Miniaturansichten für Bilder. Wir verschieben diese Aufgabe, damit sie vom Warteschlangenarbeiter verarbeitet werden kann.

Erstellen Sie eine Controller-Datei unter app / Http / Controller / ImageController.php Wie nachfolgend dargestellt.

validate ($ request, ['demo_image' => 'erforderlich | 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']); // Db-Eintrag dieses Bildes vornehmen $ image = new Image; $ image-> org_path = 'images'. DIRECTORY_SEPARATOR. $ input ['demo_image']; $ image-> save (); // die Verarbeitung der Bildminiaturen verzögern ProcessImageThumbnails :: dispatch ($ image); Redirect :: to ('image / index') -> with ('message', 'Image wurde erfolgreich hochgeladen!') zurückgegeben; 

Erstellen Sie eine zugehörige Ansichtsdatei unter resources / views / upload_form.blade.php.

       Laravel       
@if (Route :: has ('login'))
@if (Auth :: check ()) Startseite @else Login Registrieren @endif
@endif

Demo-Upload-Formular

@if ($ errors-> any ())
    @foreach ($ errors-> all () als $ error)
  • $ error
  • @endforeach
@endif @if (Sitzung ('Nachricht'))
Sitzung ('Nachricht')
@endif

Zum Schluss noch Routen für die Index und hochladen Aktionen in der routen / web.php Datei.

Route :: get ('image / index', 'ImageController @ index'); Route :: post ('image / upload', 'ImageController @ upload');

In dem ImageController Controller, der Index Diese Methode wird zum Rendern eines Upload-Formulars verwendet.

öffentlicher Funktionsindex (Request $ request) return view ('upload_form'); 

Wenn der Benutzer ein Formular übergibt, wird die hochladen Methode wird aufgerufen.

public function upload (Request $ request) // upload image $ this-> validate ($ request, ['demo_image' => 'erforderlich | 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']); // Db-Eintrag dieses Bildes vornehmen $ image = new Image; $ image-> org_path = 'images'. DIRECTORY_SEPARATOR. $ input ['demo_image']; $ image-> save (); // die Verarbeitung der Bildminiaturen verzögern ProcessImageThumbnails :: dispatch ($ image); Redirect :: to ('image / index') -> with ('message', 'Image wurde erfolgreich hochgeladen!') zurückgegeben; 

Am Anfang des hochladen Bei dieser Methode wird der übliche Datei-Upload-Code angezeigt, mit dem die hochgeladene Datei in das Verzeichnis verschoben wird öffentlich / bilder Verzeichnis. Als nächstes fügen wir einen Datenbankdatensatz mit dem ein App / Bild Modell-.

Zum Schluss verwenden wir die ProcessImageThumbnails Job, um die Miniaturbildverarbeitungsaufgabe zu verschieben. Es ist wichtig zu wissen, dass es das ist Versand Methode, mit der eine Aufgabe verschoben wird. Am Ende wird der Benutzer mit einer Erfolgsmeldung zur Upload-Seite weitergeleitet.

Zu diesem Zeitpunkt wird der Job dem hinzugefügt Arbeitsplätze Tabelle zur Bearbeitung. Bestätigen wir es mit der folgenden Abfrage.

mysql> select * FROM lvl_jobs; | 1 | default | "displayName": "App \\ Jobs \\ ProcessImageThumbnails", "job": "Illuminate \\ Queue \\ CallQueuedHandler @ call", "maxTries": null, "timeout": null, "data": "commandName ":" App \\ Jobs \\ ProcessImageThumbnails "," Befehl ":" O: 31: \ "Jobs \\ Jobs \\ ProcessImageThumbnails \": 5: s: 8: \ "\ u0000 * \ u0000image \"; O: 45: \ "Illuminate \\ Contracts \\ Database \\ ModelIdentifier \": 2: s: 5: \ "class \"; s: 9: \ "App \\ Image \"; s: 2: \ "id"; i: 2; s: 6: "\ u0000 * \ u0000job"; N; s: 10: "verbindung"; N; s: 5: "queue"; N; s: 5: "delay"; N; " | 0 | NULL | 1510219099 | 1510219099 |

Sie müssen sich fragen, was braucht es, um einen Job zu bearbeiten? Mach dir keine Sorgen - das werden wir im nächsten Abschnitt besprechen.

Warteschlangenarbeiter

Die Aufgabe des Laravel-Warteschlangenarbeiters ist die Verarbeitung von Jobs, die zur Verarbeitung in die Warteschlange gestellt werden. Tatsächlich gibt es einen handwerklichen Befehl, der uns beim Starten des Queue-Worker-Prozesses hilft.

$ php Handwerker-Warteschlange: Arbeit

Sobald Sie diesen Befehl ausführen, werden anstehende Aufträge verarbeitet. In unserem Fall sollte es das verarbeiten ProcessImageThumbnails Job, der in die Warteschlange gestellt wurde, als der Benutzer zuvor ein Bild hochgeladen hatte.

$ php Handwerker-Warteschlange: Arbeit [JJJJ-MM-TT HHMMSS] Verarbeitung: App \ Jobs \ ProcessImageThumbnails [JJJJ-MM-DD HHMMSS] Verarbeitet: App \ Jobs \ ProcessImageThumbnails

Sie hätten bemerkt, dass beim Starten eines Warteschlangenarbeiters dieser so lange ausgeführt wird, bis Sie ihn manuell beenden oder das Terminal schließen. Tatsächlich wartet es darauf, dass der nächste Job verarbeitet wird. Sobald sich ein neuer Job in der Warteschlange befindet, wird dieser sofort verarbeitet, wenn der Warteschlangenarbeiter ausgeführt wird.

Natürlich können wir es nicht so weiterlaufen lassen, also müssen wir einen Weg finden, den Warteschlangenarbeiter permanent im Hintergrund auszuführen.

Zu unserer Rettung gibt es verschiedene Prozessmanagement-Tools, aus denen Sie wählen können. Um nur einige zu nennen, hier eine Liste:

  • Zirkus
  • Daemontools
  • Monit
  • Supervisor
  • Emporkömmling

Sie sollten ein Tool auswählen, mit dem Sie den Laravel-Warteschlangen-Worker verwalten können. Grundsätzlich möchten wir sicherstellen, dass der Queue-Worker unbegrenzt ausgeführt wird, sodass er Aufträge in der Warteschlange sofort verarbeitet.

Das ist also die Queue-API, die Ihnen zur Verfügung steht. Sie können es in Ihrer täglichen Entwicklung verwenden, um zeitraubende Aufgaben zur Verbesserung der Benutzererfahrung zu verschieben.

Fazit

In diesem Artikel haben wir die Warteschlangen-API in Laravel beschrieben. Dies ist sehr hilfreich, wenn Sie die Verarbeitung ressourcenaufwendiger Aufgaben verschieben möchten.

Wir begannen mit einer grundlegenden Einführung in die Warteschlangen-API, in der Verbindungen, Warteschlangen und Jobs besprochen wurden. In der zweiten Hälfte des Artikels haben wir einen benutzerdefinierten Warteschlangenjob erstellt, der demonstriert, wie Sie die Warteschlangen-API in der realen Welt verwenden können.

Für diejenigen unter Ihnen, die entweder gerade mit Laravel beginnen oder Ihr Wissen, Ihre Site oder Anwendung mit Erweiterungen erweitern möchten, haben wir eine Vielzahl von Möglichkeiten, die Sie in Envato Market lernen können.

Sie können das nachstehende Feedback-Formular verwenden, um Ihre Fragen und Vorschläge zu posten.