In questo articolo, esploreremo l'API Queue nel framework web di Laravel. Consente di rinviare le attività ad alta intensità di risorse durante l'esecuzione dello script per migliorare l'esperienza generale dell'utente finale. Dopo aver introdotto la terminologia di base, lo dimostrerò implementando un esempio reale.
Il tempo di caricamento delle pagine è un aspetto importante di qualsiasi sito web di successo e non bisogna trascurare l'importanza di questo dato che influisce sulla SEO del sito e sull'esperienza complessiva dell'utente finale. Più spesso, si finisce per dover eseguire il debug di pagine Web con tempi di caricamento lunghi della pagina. Naturalmente, ci sono diversi approcci che potresti usare per correggere questo problema.
Dopo un'indagine, capisci spesso che ci sono determinati blocchi di codice che causano un ritardo nell'esecuzione della pagina. La prossima cosa che potresti provare è identificare blocchi che possono essere differiti per l'elaborazione e che non hanno alcun impatto reale sul risultato finale della pagina corrente. Questo dovrebbe davvero migliorare la velocità generale della pagina web in quanto abbiamo eliminato i blocchi di codice che causavano un ritardo.
Oggi, esploreremo un concetto simile nel contesto del framework web di Laravel. In effetti, Laravel fornisce già un'utile API integrata che ci consente di rinviare l'elaborazione delle attività, l'API della coda. Senza perdere molto del tuo tempo, andrò avanti e discuterò gli elementi di base dell'API Queue.
Lo scopo principale dell'API Queue è eseguire i lavori che vengono aggiunti in una coda. Successivamente, la coda potrebbe appartenere a una connessione specifica e tale connessione potrebbe appartenere a un driver di coda specifico configurato con tale connessione stessa. Cerchiamo brevemente di capire cosa ho appena detto.
Allo stesso modo, avresti usato un driver diverso per la tua connessione al database, potresti anche scegliere tra una varietà di diversi driver di coda. L'API della coda supporta diversi adattatori come database, beanstalkd, sqs e redis.
Il driver di coda è solo un posto che viene utilizzato per memorizzare le informazioni relative alla coda. Pertanto, se si utilizza un driver di coda del database, ad esempio, il nuovo lavoro verrà aggiunto nella tabella dei lavori nel database. D'altra parte, se hai configurato redis come driver di coda predefinito, il lavoro verrà aggiunto al server redis.
L'API della coda fornisce anche due driver speciali per le code a scopo di test: sincronizzazione e null. Il driver della coda di sincronizzazione viene utilizzato per eseguire immediatamente un processo di coda, mentre il driver della coda nulla viene utilizzato per saltare un lavoro in modo che non venga eseguito affatto.
Quando si configura l'API della coda per la prima volta, è necessario specificare una connessione predefinita da utilizzare per l'elaborazione della coda predefinita. Per lo meno, la connessione dovrebbe fornire le seguenti informazioni:
Quando aggiungi un lavoro in una coda, verrà aggiunto alla coda predefinita. In realtà, nella maggior parte dei casi dovrebbe andare bene, a meno che non si abbiano lavori a cui è necessario dare maggiore priorità rispetto ad altri lavori. In tal caso, è possibile creare una coda denominata alto e posizionare i lavori con priorità più alta in quella particolare coda.
Quando si esegue una coda che elabora lavori in coda, è possibile passare facoltativamente --coda
parametro, che consente di elencare i nomi delle code nell'ordine in cui devono essere elaborati. Ad esempio, se si specifica --code = alto, di default
, per prima cosa elaborerà i lavori nel alto coda, e una volta completata, recupera i lavori nella coda predefinita.
Un lavoro nell'API coda è un'attività che viene differita dal flusso di esecuzione principale. Ad esempio, se si desidera creare una miniatura quando l'utente carica un'immagine dal front-end, è possibile creare un nuovo lavoro che gestisca l'elaborazione della miniatura. In questo modo, è possibile rinviare l'attività di elaborazione delle miniature dal flusso di esecuzione principale.
Questa era un'introduzione di base alla terminologia dell'API Queue. Dalla prossima sezione in poi, esploreremo come creare un lavoro di coda personalizzato ed eseguirlo usando un operatore di coda di Laravel.
A questo punto, dovresti sentirti sicuro riguardo ai lavori in coda. Da questa sezione in poi, implementeremo un esempio reale che dimostra il concetto di lavori in coda in Laravel.
Più spesso, si finisce nella situazione in cui è necessario creare diverse versioni di anteprima di un'immagine caricata da un utente. Nella maggior parte dei casi, lo sviluppatore tenta di elaborarlo in tempo reale in modo che vengano create immediatamente diverse versioni di immagini quando l'utente carica un'immagine.
Sembra un approccio ragionevole se creerai un paio di versioni e non ci vorrà troppo tempo. D'altra parte, se hai a che fare con un'applicazione che richiede un'elaborazione pesante e quindi consuma più risorse, l'elaborazione in tempo reale potrebbe finire in una brutta esperienza utente.
L'ovvia opzione che ti viene in mente in primo luogo è quella di posticipare l'elaborazione della generazione delle miniature il più tardi possibile. L'approccio più semplice che potresti implementare in questo specifico scenario è impostare un cron job che attivi l'elaborazione ad intervalli regolari, e dovresti stare bene.
Un approccio molto migliore, d'altra parte, è di posticipare e spingere l'attività in una coda, e lasciare che l'elaboratore della coda la elabori quando ha la possibilità di farlo. In un ambiente di produzione, il gestore code è uno script daemon che è sempre in esecuzione e che elabora le attività in una coda. L'ovvio vantaggio di questo approccio è una migliore esperienza dell'utente finale e non è necessario attendere la cron run poiché il lavoro verrà elaborato il prima possibile.
Suppongo che sia sufficiente una teoria per iniziare con un'implementazione reale.
Nel nostro caso, useremo il Banca dati
driver di coda, e ci richiede di creare il lavori
tabella nel database. Il lavori
la tabella contiene tutti i lavori che devono essere elaborati nella prossima esecuzione della coda di lavoro.
Prima di andare avanti e creare il lavori
tabella, cambiamo la configurazione della coda predefinita da sincronizzare
a Banca dati
nel config / queue.php
file.
... / * | ---------------------------------------------- ---------------------------- | Default Queue Driver | ---------------------------------------------- ---------------------------- | | L'API della coda di Laravel supporta un assortimento di back-end tramite un singolo | API, offrendoti un comodo accesso a ciascun back-end utilizzando lo stesso | sintassi per ognuno. Qui puoi impostare il driver di coda predefinito. | | Supportato: "sync", "database", "beanstalkd", "sqs", "redis", "null" | * / 'default' => env ('QUEUE_DRIVER', 'database'), ...
In effetti, Laravel fornisce già un comando artigianale che ci aiuta a creare il lavori
tavolo. Esegui il seguente comando nella root della tua applicazione Laravel, e dovrebbe creare la necessaria migrazione del database che crea il lavori
tavolo.
Coda artigianale $ php: tabella
Il file di migrazione generato in Database / migrazioni / YYYY_MM_DD_HHMMSS_create_jobs_table.php
dovrebbe assomigliare a questo:
bigIncrements ( 'id'); $ Tavola-> string ( 'coda'); $ Tavola-> LongText ( 'payload'); $ Tavola-> unsignedTinyInteger ( 'tentativi'); $ Tavola-> unsignedInteger ( 'reserved_at') -> nullable (); $ Tavola-> unsignedInteger ( 'available_at'); $ Tavola-> unsignedInteger ( 'created_at'); $ table-> index (['queue', 'reserved_at']); ); / ** * Invertire le migrazioni. * * @return void * / public function down () Schema :: dropIfExists ('jobs');
Quindi, eseguiamo il migrare
comando in modo che in realtà crei il lavori
tabella in un database.
php artisan migrate
Questo è fino al lavori
la migrazione è preoccupata.
Quindi, creiamo il Immagine
modello che verrà utilizzato per gestire le immagini caricate dall'utente finale. Il modello di immagine richiede anche una tabella di database associata, quindi useremo il --migrare
opzione durante la creazione di Immagine
modello.
php artigianale: modello Immagine - migrazione
Il comando precedente dovrebbe creare il Immagine
modello di classe e una migrazione del database associato pure.
Il Immagine
la classe del modello dovrebbe assomigliare a questa:
E il file di migrazione del database dovrebbe essere creato su
Database / migrazioni / YYYY_MM_DD_HHMMSS_create_images_table.php
. Vogliamo anche memorizzare il percorso originale dell'immagine caricata dall'utente finale. Rivediamo il codice delImmagine
file di migrazione del database per assomigliare al seguente.incrementi ( 'id'); $ Tavola-> timestamp (); $ Tavola-> string ( 'org_path'); ); / ** * Invertire le migrazioni. * * @return void * / public function down () Schema :: dropIfExists ('images');Come puoi vedere, abbiamo aggiunto il
$ Tavola-> string ( 'org_path')
colonna per memorizzare il percorso dell'immagine originale. Quindi, devi solo eseguire ilmigrare
comando per creare effettivamente quella tabella nel database.$ php artisan migrateE questo è fino al
Immagine
modello è interessato.Successivamente, creiamo un processo di coda effettivo responsabile dell'elaborazione delle miniature delle immagini. Per l'elaborazione delle miniature, utilizzeremo una libreria di elaborazione delle immagini molto popolare: l'immagine di intervento.
Per installare la libreria Image di Intervention, andare avanti ed eseguire il seguente comando nella directory principale dell'applicazione.
$ php composer.phar richiede l'intervento / immagineOra è il momento di creare il
Lavoro
classe, e useremo un comando artigiano per farlo.$ php artisan make: job ProcessImageThumbnailsQuello dovrebbe creare il
Lavoro
modello di classe aapp / Lavoro / ProcessImageThumbnails.php
. Sostituiamo il contenuto di quel file con il seguente.immagine = $ immagine; / ** * Esegui il lavoro. * * @return void * / public function handle () // accede al modello in coda per l'elaborazione $ image = $ this-> image; $ full_image_path = public_path ($ image-> org_path); $ resized_image_path = public_path ('thumbs'. DIRECTORY_SEPARATOR. $ image-> org_path); // crea immagini thumb dall'immagine originale $ img = \ Image :: make ($ full_image_path) -> ridimensiona (300, 200); $ Img-> save ($ resized_image_path);Quando l'addetto alla coda inizia a elaborare un lavoro, cerca
maniglia
metodo. Quindi è ilmaniglia
metodo che mantiene la logica principale del tuo lavoro.Nel nostro caso, dobbiamo creare una miniatura di un'immagine caricata dall'utente. Il codice del
maniglia
il metodo è piuttosto semplice: recuperiamo un'immagine dalImageModel
modella e crea una miniatura utilizzando la libreria Immagine di intervento. Certo, dobbiamo passare il corrispondenteImmagine
modello quando spediamo il nostro lavoro, e lo vedremo tra un momento.Per testare il nostro lavoro appena creato, creeremo un semplice modulo di caricamento che consente all'utente di caricare un'immagine. Naturalmente, non creeremo le miniature delle immagini subito; differiremo quell'attività in modo che possa essere elaborata dall'operatore della coda.
Creiamo un file di controller su
app / Http / Controller / ImageController.php
come mostrato di seguito.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']); // crea una voce db di quell'immagine $ image = new Image; $ image-> org_path = 'images'. DIRECTORY_SEPARATOR. $ Input [ 'demo_image']; $ Immagine-> save (); // posticipa l'elaborazione delle miniature dell'immagine ProcessImageThumbnails :: dispatch ($ image); return Redirect :: to ('image / index') -> with ('message', 'Immagine caricata con successo!');Creiamo un file di visualizzazione associato a
Resources / views / upload_form.blade.php
.laravel @if (Route :: has ('login')))@if (Auth :: check ()) Home @else Accedi Register @endif@finisci seModulo di caricamento demo
@if ($ errors-> any ())@endif @if (sessione ('messaggio'))@foreach ($ errors-> all () come $ errore)
- $ error
@endforeachsessione ('messaggio')@finisci seInfine, aggiungiamo percorsi per il
indice
ecaricare
azioni nelpercorsi / web.php
file.Route :: get ('image / index', 'ImageController @ index'); Route :: post ('image / upload', 'ImageController @ upload');Nel
ImageController
controller, ilindice
il metodo è usato per rendere un modulo di upload.indice di funzione pubblica (richiesta $ richiesta) visualizzazione di ritorno ('upload_form');Quando l'utente invia un modulo, il
caricare
il metodo è invocato.upload di funzioni pubbliche (richiesta $ richiesta) // carica immagine $ this-> convalida ($ 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']); // crea una voce db di quell'immagine $ image = new Image; $ image-> org_path = 'images'. DIRECTORY_SEPARATOR. $ Input [ 'demo_image']; $ Immagine-> save (); // posticipa l'elaborazione delle miniature dell'immagine ProcessImageThumbnails :: dispatch ($ image); return Redirect :: to ('image / index') -> with ('message', 'Immagine caricata con successo!');All'inizio del
caricare
metodo, noterai il solito codice di caricamento del file che sposta il file caricato nel file/ immagini pubbliche
directory. Successivamente, inseriamo un record del database usando ilApp / Immagine
modello.Finalmente, usiamo il
ProcessImageThumbnails
lavoro per rinviare l'attività di elaborazione delle miniature. È importante notare che è ilspedizione
metodo utilizzato per rinviare un'attività. Alla fine, l'utente viene reindirizzato alla pagina di caricamento con un messaggio di successo.A questo punto nel tempo, il lavoro viene aggiunto al
lavori
tavolo per l'elaborazione. Confermiamo inviando la seguente domanda.mysql> seleziona * FROM lvl_jobs; | 1 | default | "DisplayName": "App \\ Lavoro \\ ProcessImageThumbnails", "lavoro": "Illuminare \\ coda \\ CallQueuedHandler @ chiamare", "maxTries": null, "timeout": "dati" null,: "CommandName ":" App \\ Lavoro \\ ProcessImageThumbnails " "comando": "O: 31: \" App \\ Jobs \\ ProcessImageThumbnails \ ": 5: s: 8: \" \ u0000 * \ u0000image \"; O: 45: \ "Illuminate \\ \\ Contratti di database \\ ModelIdentifier \": 2: s: 5: \ "classe \"; s: 9: \ "App \\ Immagine \"; s: 2: \ "id \"; i: 2; s: 6: \ "\ u0000 * \ u0000job \"; N; s: 10: \ "collegamento \"; N; s: 5: \ "coda \"; N; s: 5: \ "delay \"; N; " | 0 | NULL | 1510219099 | 1510219099 |Ti starai chiedendo, cosa serve per elaborare un lavoro, allora? Non preoccuparti, è quello che discuteremo nella prossima sezione.
Queue Worker
Il lavoro del responsabile della coda di Laravel consiste nell'elaborare i lavori che vengono messi in coda per l'elaborazione. Di fatto, esiste un comando artigiano che ci aiuta ad avviare il processo di lavoro in coda.
Coda artigianale $ php: lavoroNon appena esegui quel comando, elabora i lavori in sospeso. Nel nostro caso, dovrebbe elaborare il
ProcessImageThumbnails
lavoro che è stato messo in coda quando l'utente ha caricato un'immagine in precedenza.$ php artisan queue: work [YYYY-MM-DD HHMMSS] Elaborazione: App \ Jobs \ ProcessImageThumbnails [AAAA-MM-GG HHMMSS] Elaborato: App \ Jobs \ ProcessImageThumbnailsAvresti notato che quando avvii un addetto alla coda, continua a funzionare finché non lo uccidi manualmente o chiudi il terminale. In realtà, è in attesa che il prossimo lavoro venga elaborato. Non appena c'è un nuovo lavoro in coda, verrà elaborato immediatamente se l'addetto alla coda è in esecuzione.
Ovviamente, non possiamo mantenerlo in esecuzione in questo modo, quindi dobbiamo trovare un modo per far sì che l'addetto alla coda funzioni in modo permanente in background.
Per il nostro salvataggio, ci sono diversi strumenti di gestione dei processi che puoi scegliere. Per citarne alcuni, ecco un elenco:
Dovresti scegliere uno strumento con cui ti senti a tuo agio per gestire il gestore della coda di Laravel. Fondamentalmente, vogliamo essere sicuri che l'addetto alla coda debba essere eseguito a tempo indeterminato in modo che elabori immediatamente i lavori in coda.
Quindi questa è l'API della coda a tua disposizione. È possibile utilizzarlo nello sviluppo quotidiano per rinviare le attività che richiedono tempo per migliorare l'esperienza dell'utente finale.
In questo articolo, abbiamo discusso l'API Queue in Laravel, che è davvero utile se si desidera rinviare l'elaborazione di attività che consumano risorse.
Abbiamo iniziato con un'introduzione di base all'API Queue, che prevedeva una discussione su connessioni, code e lavori. Nella seconda metà dell'articolo, abbiamo creato un processo di coda personalizzato che dimostrava come utilizzare l'API Queue nel mondo reale.
Per quelli di voi che stanno appena iniziando con Laravel o stanno cercando di espandere le vostre conoscenze, il vostro sito o la vostra applicazione con estensioni, abbiamo una varietà di cose che potete studiare nel mercato Envato.
Sentiti libero di utilizzare il modulo di feedback qui sotto per pubblicare domande e suggerimenti.