Laravel al permitir poder hacer toda clase de sistemas desde sencillos a complejos, muchas veces estas tareas pasando por un alto computo, y es una de las desventajas principales que tenemos en las aplicaciones web con respecto a las aplicaciones de escritorio, y es que las aplicaciones web, usualmente (las tradicionales al menos) tienen menos recursos de cómputo disponibles, o son más limitados y esto es algo que vemos en hacer operaciones sencillas como enviar un correo o procesar una imagen, que al emplear el hilo principal del servidor (el mismo que empleamos a momento de hacer peticiones al servidor) vemos que el servidor tarda unos pocos segundos en devolver una respuesta y es este tiempo adicional el empleado para hacer estas tareas completas. Adicionalmente, si la operación a realizar supera la capacidad de cómputo o muchas personas al mismo tiempo realizan operaciones de este tipo, el servidor puede dar un error de agotamiento del tiempo (time exhaustion).
Por lo comentado en el anterior párrafo, es que debemos de emplear un mecanismo para poder hacer todos estos procesos de manera eficiente, y la forma que tenemos de hacer esto, es delegando estas operaciones, en vez de hacerlas el hilo principal, podemos. Enviarle estas tareas a un proceso (o varios dependiendo de como lo configuremos) el cual se encarga de ir procesando tareas de manera consecutiva una detrás de la otra y con esto, ya introducimos la definición de colas y trabajos.
Los trabajos son estas operaciones costosas a nivel de computo, enviar un correo, procesar una imagen, procesar un archivo excel, generar un pdf, etc, los cuales son asignados o enviados a una cola o colas (dependiendo de como lo configuremos) y de van procesando de manera eficiente es decir, podemos habilitar una cantidad determinada de procesos secundarios que son manejados por las colas para procesar estas tarea por lo tanto, con este sistema, no importa cuantos trabajos existan en un mismo tiempo, que se irán procesando de a poco sin saturar el sistema. Adicionalmente, es posible especificar prioridades en los trabajos para que se ejecuten antes que otros.
En definitiva, al emplear el sistema de colas y trabajadores, se mejora la capacidad de respuesta, es posible incrementar de manera horizontal la cantidad de trabajadores disponibles para procesar estos trabajos, es posible volver a ejecutar los trabajos fallidos, dando con esto una mejor tolerancia a fallos al sistema, todo esto, de manera asíncrona sin afectar al hilo principal
Así que aclarado la importancia de este sistema, vamos a conocer cómo implementarlo.
Primero, debemos de elegir un controlador de colar para emplear entre todos los existentes:
Por defecto, está configurado el de la base de datos:
config\queue.php
'default' => env('QUEUE_CONNECTION', 'database')
Y para realizar las siguientes pruebas, puedes emplear el de database aunque, usualmente Redis es una excelente opción por ser una base de datos rápida y eficiente y que instalamos anteriormente y es la que usaremos:
config\queue.php
'default' => env('QUEUE_CONNECTION', 'redis')
Finalmente, iniciamos el proceso para ejecutar los trabajos mediante:
$ php artisan queue:work
Y veremos por la consola:
INFO Processing jobs from the [default] queue.
Cada vez que se procesa un trabajo, verás por la terminal:
.................................................................... 3s DONE
2024-07-12 09:44:31 App\Jobs\TestJob ............................................................................... RUNNING
2024-07-12 09:44:34 App\Jobs\TestJob ............................................................................... 3s DONE
2024-07-12 09:45:43 App\Jobs\TestJob ............................................................................... RUNNING
No importa si desde tus controladores o similares despachas trabajos y la cola NO está activa, Laravel las registras y cuando actives el proceso de la cola, las despacha; y esto es todo, ya con esto Laravel levanta un proceso para gestionar los trabajos, falta crear el trabajo que veremos en el siguiente apartado.
En esta entrada vamos a conocer el uso de las Colas y los Trabajos en Laravel (Queues y Jobs) para poder realizar trabajos en segundo plano.
La idea de esta API es que nosotros podemos aplazar tareas (dejarlas en segundo plano) que requieren un alto consumo de computo y todo esto es para mejorar la experiencia del usuario y evitar cuelgues en la aplicación; de tal manera que estas tareas de alto cómputo se ejecutarán en otro hilo o proceso en nuestro servidor y se irán resolviendo a medida que lleguen o dependiendo de la prioridad de las mismas.
Básicamente todo este proceso se lleva a cabo entre las tareas/trabajos/jobs (los procesos elevados de cómputo) y las colas (mecanismo para registrar los jobs).
De igual manera vamos a hablar un poco más en detalle de estos dos componentes fundamentales.
Los trabajos son la tarea pesada o que requieren mucho procesamiento que queremos aplazar; y pueden ser de cualquier tipo como envío masivo o simple de emails, procesar imágenes, vídeos etc; por lo tanto son estas tareas que nosotros vamos registrando como pendientes para que Laravel las vaya procesando uno a uno a medida que esta disponible; asi que lo siguiente que te puedes preguntan es, ¿Cómo se maneja esta organización?; es decir, quien es el que se encarga de manejar la prioridad entre tareas o trabajos (colas) y cómo mantenemos una organización de todo esto.
En Laravel, los jobs son una parte importante de la funcionalidad de la cola de trabajos del framework, es decir los jobs son usados para procesar los trabajos pesados almacenados mediante “colas”; estas tareas pesadas pueden ser cualquier cosa como envio de emails, procesar imágenes, vídeos entre otros; esto es ideal ya que, estas tareas no forman parte de la sesión principal del usuario y se evita consumir recursos de la sesión principal del usuario, aparte de que, se evita las famosas ventanas de “no responde” y en general, se tiene una mejor experiencia en el uso de la aplicación.ya que no afecta el rendimiento o la capacidad de respuesta de la aplicación principal.
Los jobs en Laravel pueden ser creados para realizar cualquier tarea que se necesite en el back-end sin que el usuario tenga que esperar a que se complete la tarea; es decir, como enviar un correo o exportar datos en un excel o un formato similar.
Lo estupendo de los jobs es que, se ejecutan de manera secuencial, suponte que creas un job para procesar correos, los correos se van enviando uno a uno sin necesidad de sobrecargar la página, cosa que no sucederia si el envio de correos se manejada desde la sesión principal del usuario y de repente, vengan 5 o más usuarios a enviar correos desde la aplicación, por lo tanto, en un mismo instante de tiempo, tendrias múltiples envios de correos y gastando los recursos que esto requiera.
En resumen, los jobs en Laravel son una parte esencial de la cola de trabajos del framework, y permiten que las tareas pesadas o no esenciales se realicen en segundo plano para mejorar el rendimiento y la capacidad de respuesta de la aplicación principal.
Ya en este punto, hemos introducido el concepto de “colas” en el uso de los jobs, de igual manera, vamos a explicarlo rápidamente; las colas de trabajo corresponden a la operación que se quiere realizar, que como comentamos antes, corresponde a la operación “pesada” que se quiere realizar, es decir, en vez de enviar un correo desde un controlador, se almacena en una cola que luego es procesado mediante otro proceso.
La respuesta a lo comentado anteriormente es bastante simple, serían las colas como mecanismo que permiten registrar o añadir estos trabajos o jobs; podemos registrar o tener tantas colas como queramos y podemos especificar a Laravel mediante artisan que colas queremos que procesen primero; por ejemplo, veamos el siguiente ejemplo:
php artisan queue:work --queue=high,default
Mediante el comando anterior le estamos diciendo a Laravel que primero procese los trabajos de una cola llamada "hight" y luego lo de una cola llamada "default", que por cierto, es la cola que tenemos definida por defecto.
Las conexiones son la manera predeterminada que tenemos para indicar cómo se va a llevar a cabo todo el proceso de las colas (ya que recuerda que la cola absorbe a la tarea, por lo tanto, en este punto, una vez registrada la tarea o job en una cola, en nuestro cola la tarea ya no pinta nada); pero para poder emplear toda esta estructura debemos indicar la conexión y con ella debemos indicar:
Por lo tanto, mediante la conexiones nosotros podemos especificar el driver que vamos a emplear que puede ser cualquier como la base de datos u otros servicios; por ejemplo:
Base de datos:
Y algunos parámetros extra para la configuración.
Ahora vamos a abrir el archivo de config/queue.php
y el .env
, en los cuales vamos a buscar una configuración llamada QUEUE_CONNECTION
Que por defecto se llama QUEUE_CONNECTION
y tiene la configuración de sync
, que si lo analizas un poco verás que tenemos varios tipos de conexiones que podemos emplear, entre ella la llamada database que es la que vamos a emplear, por lo tanto configúralo al menos en el archivo de .env
; en mi caso lo voy a dejar así en el .env
:
QUEUE_CONNECTION=database
Y en el config/queue.php quede:
'default' => env('QUEUE_CONNECTION', 'database'),
Ahora bien lo siguiente que de puedes preguntar sería, ¿cómo nosotros podemos configurar la tabla en nuestra base de datos?; siguiente la documentación oficial:
php artisan queue:table php artisan migrate
Ya tenemos un comando de artisan que nos ayuda en todo este proceso, que sería el que nos permite generar la migración para crear la tabla; y con esto estamos listos.
Ahora vamos a crear nuestro primer Job que vamos a configurar con la cola de default; para eso, vamos a crear uno mediante nuestro artisan:
php artisan make:job ProcessImageSmall
Y con esto tenemos un archivo generado en App\Jobs
El cual consta de dos bloques principales:
La función constructora para inicializar los datos básicos que vamos a emplear y la función de handle para hacer el proceso pesado; así de simple, por lo tanto en la función de handle podemos enviar los emails, procesar videos o imágenes, para nuestro ejemplo vamos a suponer que tenemos una imagen que estamos recibiendo por parámetros:
protected $image;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(PostImage $image)
{
$this->image = $image;
}
Esta imagen es básicamente una instancia de un modelo que luce de la siguiente manera:
class PostImage extends Model
{
protected $fillable = ['post_id', 'image'];
public function post(){
return $this->belongsTo(Post::class);
}
public function getImageUrl(){
return URL::asset('images/'.$this->image);
//return Storage::url($this->image);
}
}
Y ahora, vamos a hacer un proceso pesado como escalar una imagen; para esto, vamos a emplear el siguiente paquete que podemos instalar mediante composer:
composer require intervention/image
El código que vamos a emplear, básicamente se auto explica solo:
<?php
namespace App\Jobs;
use App\PostImage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Intervention\Image\ImageManagerStatic;
class ProcessImageSmall implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $image;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(PostImage $image)
{
$this->image = $image;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$image = $this->image;
$fullPath = public_path('images' . DIRECTORY_SEPARATOR . $image->image);
$fullPathSmall = public_path('images' . DIRECTORY_SEPARATOR . 'small' . DIRECTORY_SEPARATOR . $image->image);
$img = ImageManagerStatic::make($fullPath)->resize(300,200);
$img->save($fullPathSmall);
}
}
En el cual simplemente creamos una instancia de nuestro paquete, que instalamos anteriormente, especificamos la ubicación de la imagen y mediante la función de resize escalamos la imagen a las dimenciones especificadas; luego, guardamos la nueva imagen y con esto estamos listos.
Lo siguiente que tenemos que especificar, seria en donde nosotros vamos a llamar a este trabajo, que puede ser en cualquier parte de nuestra aplicación como cuando nosotros cargamos una imagen, etc; supongamos que tenemos un método para cargar una imagen en Laravel por ejemplo:
public function image(Request $request, Post $post)
{
$request->validate([
'image' => 'required|mimes:jpeg,bmp,png|max:10240', //10Mb
]);
$filename = time() . "." . $request->image->extension();
$request->image->move(public_path('images'), $filename);
//$path = $request->image->store('public/images');
$image = PostImage::create(['image' => /*$path*/ $filename, 'post_id' => $post->id]);
ProcessImageSmall::dispatch($image);
return back()->with('status', 'Imagen cargada con exito');
}
Desde aquí; si te fijas bien en el código, verás que definimos una instancia de nuestra cola con el método de dispatch
para despachar el trabajo ProcessImageSmall::dispatch($image)
Ahora si revisamos la tabla anterior, veremos que se registró un trabajo, pero el mismo no ha sido despachado, para despachar el mismo, tenemos que activar el demonio que se encarga de hacer esta labor, levantar el proceso que se encarga de hacer los trabajos pendientes en la tabla jobs:
php artisan queue:work
Y con esto veremos que tenemos todo listo y el trabajo ya fue despachado:
Con esto, aprendimos a emplear los trabajos y las colas en Laravel; recuerda que esto es uno de los muchísimos temas que tratamos en profundidad en nuestro curso de Laravel que puedes tomar en esta plataforma en la sección de cursos.
Ahora sí vamos a procesar la cola como te digo importante que puedes tener tu supervista con View mezclado con read mezclado con un botón que envíe un cohete a la luna Puedes hacer cualquier cosa lo que quiero decir que otra vez esto es independiente al flujo normal de la aplicación entonces de momento creo que he recargado un par de veces que fue lo lo que hice la anterior clase vamos a ver qué pasa aquí lo primero que tenemos que hacer es abrir el archivo de log para tenerlo aquí controlado. Te pediría que aquí aparece el tiempo en el cual está tardando para cargar la página si lo hace rapidito como estamos en local el proceso va a ser muy rápido, par este job, voy a colocar unos 3 segundos que se detenga mediante un sleep que simula enviar un correo o cualquier cosa y luego termina aquí la operación Entonces por aquí vamos a empezar a despachar las colas también pendiente porque va a procesar las colas bueno los trabajos:
<?php
class Test implements ShouldQueue
{
***
public function handle()
{
sleep(3);
Log::info('Test.');
sleep(3);
}
}
Al ejecutar el comando de:
$ php artisan queue:work
Si tienes algunos trabajos acumulados, se irán a procesar automáticamente.
Aquí puedes ver que los está procesando es decir otra vez no se perdieron esos trabajos que hicimos Antes aunque la cola no estuviera activa por lo tanto esto lo da solidez a nuestro proyecto, a nuestra aplicación en general ya que otra vez eso se van a perder y en caso de que Existe algún problema también recuerda que bueno más adelante te lo digo pero también tenemos un comando ahí de tried:
$ php artisan queue:work --tried=3
En el cual le colocamos simplemente indicamos las veces en las cual va reintentar hacer otra vez la operación por si cualquier cosa haya sucedido Al momento de ejecutar esa tarea ocurrió algún problema Entonces es básicamente eso.
Bueno si reventamos aquí en el cual indica el servidor que no pudo procesar la petición en un tiempo determinado o algo en desarrollo entonces imagínate como fuera en producción que vamos a tener un ambiente más controlado o con menos recursos pero aquí puedes ver cómo va funcionando entonces imagínate otra vez que esto es precisamente enviar un correo una operación que tarda varios segundos por cliente y varios clientes se conectan al mismo tiempo obviamente la aplicación o el servidor se va a haber superado en base al poder de cómputo y de memoria y en es y en ese punto daría una sección Y por supuesto Se perdería el trabajo o el progreso que está haciendo el cliente y con esto También aparte de todo el tiempo que está el cliente aquí esperando a que se termine la operación obviamente eso no sería un ambiente recomendado pero si hacemos aquí mediante este esquema simplemente va a ir procesando una tarea uno a uno tal cual veía Y eso también es un punto muy importante si venimos acá nosotros y esto lo voy a hacer para simular varios clientes nosotros aquí suponte que vienen tres clientes Cómo puedo simular aquí tres clientes bueno puedo recargar esto tres veces por lo tanto vamos a tener tres trabajos que otra vez lo puede simular como si fueran tres clientes apartes entonces vengo acá recargo aquí tres veces Bueno recargué como cuatro veces y vas a ver que él va a ir haciendo la ación uno a uno por lo tanto no se va a saturar y era aquí el ejemplo que te daba entre es muy diferente.
Si tú vas a transportar 20 cajas suponte que son 20 cajas para una laptop, es decir son una caja más o menos grande es muy diferente Si te dan esas 20 cajas de golpe que no las vas a poder manejar porque son muchas cajas para cargarlas tú en las manos es muy diferente a que te den una caja por una y tú la vayas a ir manipulando y colocándola en el sitio final Entonces esto es un buen ejemplo de esto y por lo tanto aquí no es como quien dice coloquialmente se caería el servidor no tendría un escape de memoria o como sea que se llame el error y por lo tanto puede ir procesando un trabajo poco a poco y no de manera paralela Y eso es otro punto muy importante que tenemos aquí en el uso de las colas y los trabajos así que bueno aclarado esto Recuerda que si tienes todavía alguna duda puedes ir a ver el video de que me puse a dibujar cajitas o el de la presentación Porque es importante que entiendas Cómo es el funcionamiento de todo que en resumidas cuentas las Quiz son simplemente una cola es decir es el comando que ejecutamos antes y por lo demás todo ese todo lo demás es el trabajo que es el proceso pesado y que lo llamamos en donde nosotros queramos dependiendo de la lógica de nuestra aplicación y dependiendo lo que haga el trabajo otra vez si fuera enviar un email a un usuario registrado tú tendrías que venir aquí al de user controller Buscar aquí el de register bueno perdón register no me fui el de Store Bueno eso simulando un poquito el proceso y justamente aquí entonces Ni siquiera sería aquí porque creo que no lo tenemos expuesto user controller no no lo tenemos expuesto Pero bueno suponte que este fuera el que para el usuario final tuvieras que venir aquí y justamente una vez creado el usuario aquí colocarías tú job register dispatch le pasarías tu usuario y bueno el contenido bueno y todo lo demás el contenido Depende como lo manejes Porque si fuera un un solo trabajo para despachar todos los emails entonces aquí se le tuas que pasar el contenido o si es específico para los usuarios registrados entonces simplemente sería el usuario Pero sería eso ya una simulación de esto lo hacemos en la siguiente clase Así que vamos allá.
Vamos a hablar sobre un tema que también es muy importante que sería el de los kes en jot o colas y trabajos en español kus viene siendo colas y jot viene siendo trabajos y digo que es un tema muy importante por dos sencillas razones viendolas desde el punto de vista del sistema uno es que con esto con este esquema que todavía no conocemos nos permite mejorar las respuestas hacia el cliente y también la tolerancia a fallos al sistema Y a qué me refiero con esto porque básicamente los procesos que son de un alto nivel de cómputo como viene siendo enviar un email como viene siendo generar un PDF o leer un archivo Excel estoy hablando de que estos archivos van a tener un gran volumen de datos y por lo tanto Mientras más datos o más páginas va a ser más complicado o más largo leerlos y con esto tener un mayor consumo de cómputo a Eso es lo que me refiero creo que es bastante sencillo de entender Si por ejemplo yo voy a leer este este archivo que lo puede exportar a PDF va a ser un tiempo mayor así Simplemente Laravel lee un PDF de cinco páginas es te estoy hablando que tiene 572 páginas creo que es un poco Obvio obvio lo que te estoy comentando entonces este tipo de procesos usualmente si lo mandamos a hacerlo de la forma clásica en la cual hacemos un proceso Dead tal cual hicimos tenemos ahí un controlador que se encarga de leerlo y vamos leyendo línea por línea todo eso se hace en el hilo principal y aquí es una de las desventajas que tenemos en este tipo de esquemas en las cuales empleamos aplicaciones web Y es que si fuera una aplicación de escritorio ya podemos acceder de una mejor manera a los recursos del equipo es decir crear un hilo o algo por el estilo aquí con php o en aplicaciones web en general siempre es un poco más complicado hacer esto y es por eso que existe este tipo de mecanismos que nos permiten básicamente hacer un proceso aparte viene siendo eso básicamente en vez de ejecutar la tarea complicada o procesos complejos en el hilo principal lo podemos hacer en un hilo aparte es así de simple ahorita te hago Bueno al final de todo esto te voy a hacer unos ejercicios con unas cajitas para que se entienda un poquito mejor La idea de una manera un poco más práctica Y a partir de la siguiente clase empezamos con esto pero bueno por qué tiene esta denominación doble de dice cues en jot básicamente el jot viene siendo una clase por aquí te voy a mostrar una como lo es un un componente como es un controlador como es un modelo viene siendo una clase que hace algo que es ese algo una tarea una tarea que es tan abierta como lo que tenemos en los controladores pero claro esta tarea es un poco más cerrada no va a devolver una vista o bueno si la puede devolver en caso de que el proceso complicado a la final se traduzca en una vista Pero lo que me refiero no está obligado a devolver algo simplemente hacer una operación una operación complicada otra vez procesar una imagen o en términos generales procesar un archivo entiéndase ya sea generarlo o ya sea consumirlo es decir leerlo y luego devolver algo o hacer alguna operación en la base de datos si es necesario para este sencillo ejemplo Fíjate que lo único que hace esta tarea es colgarse por 3 segundos y esto nos va a permitir fácilmente entender cómo funciona esto ya que ya que si tú haces esta función de slip en el hilo principal lo que vas a hacer es que se bloquee por 3 segundos es decir que la página aparezca cargando por 3 segundos en el hilo principal si haces otra vez esto ya sea en el controlador componente o ruta pero si lo hacemos en el trabajo Esto va a ser un hilo aparte y simple simplemente el hilo el hilo secundario se va a quedar durmiendo 3 segundos Entonces esto viene siendo la parte del job por aquí podemos enviar un email podemos leer una imagen bueno leer un PDF o un Excel lo que sea o generar un PDF o generar una imagen todo eso lo podemos hacer justamente por acá porque es completamente libre y como puedes suponer tenemos acceso a toda la Api de arabel y sus paquetes que queramos importar entonces ahí ya tenemos el trabajo pero falta un punto extremadamente importante como demonios eje amos esto y ahí es donde entran las colas que ya es un proceso que realmente no implementamos nosotros sino simplemente lo utilizamos Que obviamente es muy personalizable ya que siempre te doy un ejemplo de que es simplemente un hilo es decir simplemente es un proceso secundario pero no tiene que ser así puedes crear dos puedes crear tres etcétera puedes crear tantos como tú requieras o que soporte tu equipo Claro está entonces esa es la parte de las colas las cuales procesan estos trabajos y es básicamente eso ya creo que cuando cuando vayamos un poco a la práctica se puede entender esto de una mejor forma de momento no quiero profundizar lo más ni enredarte más Pero recuerda que
puedes pausar básicamente esta clase y empezar a leer esto para que también lo entiendas de una manera un poco más teórica yo te digo un poco la manera más práctica y aquí te dejo la parte más teórica entonces como toda en la vida También tenemos drivers o controladores los cuales son los siguientes tampoco quiero extenderme mucho ya esto por ejemplo el de s lo ejecuta de manera asíncrona justamente Después de terminar la la respuesta bueno obviamente este utilizando el hilo principal no nos sirve mucho entonces es más que todo adecuado para entornos de pruebas y desarrollos porque otra vez no estamos ganando mucho ya que sigue trabajando en el hilo principal nosotros queremos que este proceso sea asíncrono es decir mandarle la tarea a un hilo secundario y que esto cuando termine bueno Simplemente ya terminó y y el hilo principal puede seguir en su flujo normal También tenemos el de database, bueno como hemos visto siempre no es el mejor esquema porque a la final estamos saturando otro proceso el de redis ya lo conocemos es es una base de datos de igual manera te lo introduzco rapidito En caso de que te hayas brincado algunos videos anteriores redes viene siendo una base de datos una base de datos de tipo clave valor la característica principal que es extremadamente rápida y usualmente se emplea para este tipo de operaciones ya sea para caché como lo utilizamos antes o en este caso para precisamente hacer estos procesos y es el que también vamos a emplear en este en este bloque vamos a utilizar ya sea el de database porque otra vez Es para hacer un experimento con esto o el de redis cuál controlador emplees al igual que ocurre con otras operaciones anteriores como el de la cach es completamente transparente para lo que se refiere la implementación así que no te preocupes tanto por esto y esto que tenemos acá son simplemente otros programas que podemos emplear no voy a entrar mucho en detalle ya que bueno puedes consultar la documentación de ellos simplemente colocas este nombre y por ahí puedes obtener más información pero obviamente es un programa que tiene que estar instalado al igual que nosotros tenemos redes instalado y lo referenciamos y se acabó el asunto y nul significa que vas a Deshabilitar el proceso de colas del sistema es Y eso viene siendo Prácticamente todo entonces otra vez yo sé que es un poco abstracto sobre todo por el tema que ahora son dos cosas y no solamente una como usualmente estamos acostumbrados a manejar y bueno vamos a dejarlo un poquito hasta ahí la parte teórica Entonces cómo lo configuramos como puedes suponer ya tenemos un archivo llamado queue, en este caso que es para manejar las colas.
Fíjate que es solamente queue, es decir, no se llama job; al igual que tenemos con la cache al igual que tenemos con con el email al igual que tenemos con el login al igual que tenemos con la base de datos tiene un orden muy similar simplemente aquí la variable de entorno Cuál es el que estamos empleando por defecto y por defecto estamos empleando database que te funcionaría correctamente Esto lo puedes emplear sin ningún problema yo de manera demostrativa fíjate que estoy trabajando en este porque este proyecto es el que tengo ligado con largo si no emplearía ya el de generals pero ahí tengo es laravel herds y ya sabemos que la versión gratuita de herds no tiene acceso a la base de datos entonces me tocaría instalarlo de manera paralela o verlo como habilito solamente aquí redis:
Que ya lo tengo habilitado Aunque no aparezca por aquí Qué raro pero bueno ya lo tengo aquí habilitado y bueno ya lo puedo aquí probar rapidito Entonces es precisamente para hacer esa demostración Pero tú puedes ocupar el proyecto que tú quieras otra vez si no tienes redes instalados puedes emplear el de la base de datos ya que para efectos de este de este bloque es Exactamente igual ya que es simplemente una práctica si estás en Mac puedes emplear el de de dbngin ahí está la opción de redis y por aquí te recomendarías largo Aunque habilites el de redis por aquí como te había comentado en el video anterior pero decidí separarlo vamos a hacer aquí algunas cajitas para que se entienda de una manera un poco más práctica todo esto y luego en la siguiente clase vamos a la implementación la primera implementación eh otra vez lo hago porque es un tema como es doble colas y trabajos entonces sé que entiende a la confusión inclusive al principio hace algunos años cuando también vi esto no lo terminaba de entender el porqué de todo y es por eso que quiero hacer un poco este video un poco más ilustrativo de práctica también recuerda que son videos puede que si todavía a partir de esto no lo entiendes que está bien eso pasa vayas primero a la práctica es decir veas el siguiente video y luego cualquier cosa puedes regresar tanto a la presentación como este video para que entiendas un poco de una manera más bueno más cómoda pero otra vez todo se aprendes con la práctica y bueno viendo aquí un poquito los videos de de reforzamiento Así que aclarado esto Vamos allá.
Obviamente el proceso del hilo principal cuando algún día responda que es el que tenemos acá voy a llamarlo aquí principal y obviamente nosotros a veces tenemos que hacer algunas tareas Aquí está tenemos que hacer algunas tareas que son costosas como te comentaba antes procesar archivos podemos colocarlo en términos genéricos pero otra vez puede ser cualquier cosa por ejemplo también conectarse a una Api que también es un proceso que demora cierto tiempo por ejemplo Cuando hacemos una compra de línea suponte que es como Amazon obviamente Amazon que procesa múltiples no sé cuántas ponte tus cientos de compras por minutos obviamente no va a guindar en todas esas compras va a colocar en el hilo principal la operación de compra que es comunicarse con el banco mandarle la información y obviamente haga el pago a posterior obviamente no lo va a hacer en el hilo principal porque se lo hace así obviamente cuando tenga un alto volumen de compras que casi siempre va por más que sea por más bueno que sean los servidores en algún punto van a empezar a fallar porque está quando el hilo principal del equipo qué es lo que hace Amazon simplemente los va enviando a una cola de trabajos y a partir de ahí se van procesando poco a poco y es por esto también que vemos que siempre demora algunas horas o algunos minutos inclusive días en procesar la compra claro Ellos tendrán otra otro tipo de lógicas en los cuales también harán alguna verificación y es por eso que a ve se puede tardar tanto es decir No creo que tampoco la cola dure tres días en procesarse es cuestión ya también un poco interno de ellos pero lo importante es notar que no se hace en el hilo principal Porque si fuera en el hilo principal que es cuando hacemos por ejemplo una compra con PayPal que seguramente tiene varias cosas por detras pero lo que me refiero que es un poco más transparente eh sería Expedito entonces aquí tenemos el el hilo principal y suponte en este ejemplo que queremos procesar imágenes lo lo bueno el flujo normal que es hacerlo directamente en el controlador y entiéndese que también puede ser componente sería que cuando queremos procesar aquí una imagen procesar la imagen disculpa de verdad esto aquí dice procesar imagen lo hacemos en el hilo principal por lo tanto sigue el flujo básica y esto demora cierto tiempo que otra vez depende de lo que estés procesando entonces obviamente Esto no es lo mejor y aquí es un poco lo que te comentaba que si múltiples personas suponte que esto es un proceso abierto en los cuales múltiples clientes lo pueden utilizar y suponte que muchos clientes lo hacen al mismo tiempo obviamente aquí lo que va a pasar es una de dos cosas o en el mejor de los casos la operación va a tardar más tiempo por lo tanto vas a ver ahí el navegador procesando es decir cargando cargando cargando cargando porque tiene que procesar en un hilo principal múltiples solicitudes en este caso también procesar las imágenes o simplemente el servidor se ve solapado se ve superado se ve exhausto ahí es cuando aparece los famosos mensajes de exhausto de tiempo de solicitud superado o algo por el estilo Pero a la final es que simplemente da un error 500 y es por tiempo de procesamiento que no lo pudo hacer y es por eso que básicamente con el proceso de colas y trabajos nosotros podemos solventar todo eso ya que la final en ese ejemplo Que te estoy diciendo que hay varios clientes; suponte que son 10 la aplicación está intentando procesar esas 10 solicitudes en un mismo tiempo pero cuando lo hacemos mediante las colas y trabajos no va así sino va una detrás de la otra es decir nosotros esos mismos 10 clientes utilizamos las colas de trabajo hac la solicitud al mismo tiempo lo único que va a hacer es que bueno se agrega ese trabajo a la cola y el proceso o procesos que habilitemos van a ir procesando uno a uno es decir por una parte aquí tenemos un esquema paralelo y en el otro tenemos un esquema secuencial, esa viene siendo la principal diferencia Entonces es Obviamente si a ti en te dan por ejemplo 10 cajas pero te la dan al mismo tiempo obviamente no vas a poder cargar esas 10 cajas Pero si te van dando una por una obviamente sí vas a poder procesar esas 10 cajas a eso es lo que un poco lo que yo me refiero entonces aquí Bueno ha es el problema que tenemos Y en el otro otro en vez de hacer esto que te comentaba voy a venir por aquí abajo tenemos otro esquema en el cual tenemos el hilo principal otra vez voy a llamarlo principal por aquí tenemos la tarea que queremos realizar que es la de voy a llamarla pi que es procesar imagen por dar un ejemplo y en vez de colocarlo aquí en el hilo principal que viene siendo este canal que estoy colocando acá Este viene siendo el hilo principal todo esto este flujo encerrado en esta perfecta nube este viene siendo el hilo principal o el proceso principal en vez de colocarlo aquí él lo que hace es pasárselo a un proceso secundario que viene siendo nuestra Cola y qué es lo que le pasa un trabajo un jot que viene siendo la final una clase que hace algo Pero obviamente le pasa la distancia de esto la cual puede recibir parámetros y bueno todo lo que sabemos entonces este obviamente esta Va a ser la parte del quii voy a colocarlo Aquí voy a colocarle simplemente C de cola porque no quiero que aparezca así de feo Ya tengo Jen y por aquí esto otra vez pueden ser un proceso Dos procesos tres procesos todos los procesos que tú requieras y Que obviamente soporte tu equipo no vas a poner 100,000 procesos y el por equipo no puede soportar más de dos Entonces en este ejemplo va cada cajita que tenemos aquí viene siendo un jot voy a colocar intentar colocarle J eso es una J por favor no devuelvas el curso no es para dibujar cajitas esto viene siendo los trabajos pero en vez de procesarlo otra vez de manera secuencial otra vez suponte que 10 personas hacen una solicitud como te comentaba antes para procesar una tarea bastante costosa en vez de hacerlo de manera paralela lo haces de manera secuencial entonces Simplemente ya va agregando cajitas por acá y se van procesando a medida que van recibiendo las tareas y es así de simple y esto obviamente como te digo es la cola y es eso básicamente otra vez Hazte el ejemplo de que te estás recibiendo una caja con una computadora un deop o una laptop y te están dando 10 cajas al mismo tiempo bueno puede que los soportes si no son 10 entonces pele 20 ya 20 no vas a poder agarrarlas al mismo tiempo porque se te van a caer Si te dan las las 20 cajas al mismo tiempo pero qué pasa si te van dando una a una Primero te dan una y obviamente tú la colocas en el escritorio recibes la otra la colocas en el escritorio obviamente eso sí lo vas a poder manejar pero otra vez si te dan las 20 al mismo tiempo para colocarlas en el escritorio Seguramente se te van a caer la mitad al menos Entonces ese viene siendo la diferencia y esto lo puedes comparar con el pobre serv en el cual en el hilo principal no solamente tiene que soportar las 20 lactos o los 20 procesos que le estás pasando sino también tiene que devolver una respuesta al cliente y aquí es un poco lo que te comentaba esto también a la final mejora que no lo comenté en el video anterior pero es un poco obvio al mejorar la capacidad de respuesta y también la tolerancia fallo es decir que la aplicación no pueda procesar las 10 tareas al mismo tiempo y por lo tanto falle esto mejora tanto la respuesta del de la aplicación porque no otra vez la operación no se está está haciendo en el hilo principal y también la tolerancia a fallos es decir que de errores 500 y con esto la experiencia final que puede tener el usuario en nuestra aplicación que es lo más importante que nosotros tenemos que tener en cuenta al momento de hacer cajitas perdón de hacer nuestras aplicaciones Entonces es básicamente Eso espero que con esto con este excelente diseño eh te haya quedado claro cualquier cosa te do la imagen aquí para que mentira no lo voy a dejar ya lo voy a borrar y bueno eso viene siendo Prácticamente todo Recuerda que este video lo puedes ver más adelante cuando implementos la aplicación de ejemplo en el siguiente videoo para que mediante mis excelentes dibujos puedas tener todo un poco más claro Entonces vamos allá ahora ya conocido un poco Cómo funcionan las colas y los trabajos lo siguiente que vamos a hacer sería crear un pequeño experimento para verlo aquí de manera práctica entonces bueno en la final cuando creemos ahorita nu nuestro trabajo y lo configuremos Ne si lo despachos desde alguna parte en este caso va a ser desde una ruta por ser un ejemplo ejecutaría el siguiente Comando que por defecto aquí lo podemos personalizar luego tengo algunos parámetros de personalización al final de este bloque ejecutarías el siguiente Comando para iniciar un proceso paralelo recuerda otra vez que si vas a subir esta producción ya este tipo de comando lo tienes que emplear en un servidor dedicado no puede ser en un servidor compartido es decir algo que puedas lanzar comandos mediante una terminal entonces para crear el trabajo como puedes suponer tenemos la opción de make indicamos Shot el nombre del trabajo lo mismo de siempre puedes colocar una carpeta lo que tú quieras ahorita creamos este trabajo que es lo que va a hacer es dormir el hilo y aquí guardamos algo por el log para poder ver eso un poco más en tiempo real entonces luego en alguna parte creado la clase que si no la instanci en alguna parte Simplemente no se está empleando algo como los modelos Por ejemplo tú puedes crear tu clase modelo pero si no lo empleas eh queda ahí inútil el archivo entonces en alguna parte un controlador algo que sea consumido por el cliente despachamos el trabajo lo despacha otra vez hacia la cola que ya iniciamos o bueno vamos a iniciar en ese punto que es un proceso aparte y eso
sería prácticamente todo entonces aquí también voy a traerme una ventana adicional porque aquí yo creo que lo mejor es que veamos en paralelo Claro a mí se me dificulta un poquito aquí la ventana de grabación por escalar las ventanas pero en unos momentos que veamos en paralelo Cómo va funcionando todo ya vamos a verlo en unos momentos de momento simplemente sígueme la corriente entonces para este ejemplo voy a emplear el de base de datos como te digo puedes emplear cualquiera que no sea el de nulo para no deshabilitarlo pero al rato cambiamos a redes como pero otra vez podemos iniciar con este sin ningún problema ya que estamos en un ambiente otra vez de prueba y es independiente el motor que emplees el Driver para nosotros que estamos en desarrollo Entonces vamos a comenzar creando el trabajo ya salimos de esto php artisan make colocamos jot que es lo que vamos a crear y vamos a llamarlo como test job y damos un enter y esperamos aquí no sé a veces de verdad por qué se tarda esto si simplemente es crear un archivo A veces lo hace rápido y a veces no según la temática Pero bueno aquí ya lo tenemos Bueno un poco lo obvio no te expliqué mucho la estructura pero bastante entendible esto no lo cambiamos son servicios que está empleando En caso de que sea necesario lo cambiarías pero yo es sería un enfoque un poco más avanzado y bueno para la mayoría de los casos Esto está bien el constructor es para inicializar cosas es decir cuando quieres pasarle parámetros por ejemplo para enviar un email le pasarías el usuario o el email el cuerpo el asunto todo eso sería por aquí crea crea tus atributos y por aquí los defines más adelante hacemos un pequeño ejemplo con esto y bueno la hoas de la corona sería el handle que es el que hace la operación en sí Entonces qué es lo que vamos a hacer colocamos aquí como te digo quiero guardar en el lot de manera informativa Aquí también importante que en tu lot el que estés empleando si defines el nivel que sea bueno inferior a este según la escala que definí antes ya que que queremos guardar si no aquí coloca error o lo que tú quieras pero bueno es importante que registrar logs porque si no no estamos haciendo nada por aquí importamos aquí tenemos el paquete en caso de que no te recuerdes illuminate Support fate y por ahí tiene que decir lot que lo tenemos acá y aquí tenemos esto utilizamos la función slit de php muy importante que lo que hace es dormir el proceso o el hilo sea lo que sea que lo llame y aquí le indicas la cantidad de segundos en este caso son 3 segundos eh clono acá y aquí voy a colocarle mejor before y after para que se entienda mejor Aquí coloco after y seguimos esto sería nuestro hilo otra vez por décima cuarta vez aquí tú realizas cualquier operación costosa es lo que queremos mandar a un trabajo y aquí lo tenemos definido ahora faltaría emplearlo en alguna parte si fuera Entonces lo colocarías cuando lo vayas a emplear Por ejemplo si quieres enviar un correo cuando se registra el usuario aquí sería justamente bueno tuvieras que buscar el controlador que se encarga de registrar el usuario y en algún punto justamente cuando lo registre enviarías ese correo entonces voy a volver acá a la parte de las rutas voy a crear aquí una Recuerda que estoy empleando este proyecto porque es el que tengo aquí ligado con laragon y ya tengo redis entonces aquí coloco:
.env
QUEUE_CONNECTION=redis
el nombre que le quieras dar voy a implementarlo aquí mismo para simular Bueno un controlador o sea lo que sea que quieras que lo procese y por aquí Bueno hacemos cualquier cosa retornamos nuestra supervista Ahí está y antes de esto Claro está tenemos que despachar el trabajo Es decir somos nosotros otra vez que decidimos cuándo empleamos el trabajo tal cual fuera una instancia lo puedes ver como si fuera una instancia de alguna clase que quieres crear algo y bueno para seguir con la lógica de tu controlador o el componente que estés empleando; ya la importación es lo típico, simplemente es la ubicación del archivo creo que ni lo colocó para ver Bueno ahorita vemos ahí Creo que no le importó ahora sí colocamos dispatch:
ProcessImageSmall::dispatch($image);
Los atributos eso lo vemos luego de momento conformemos con esto Okay ya ahí lo tenemos pero falta un punto importante Aunque fíjate antes de comenzar que si venimos para acá e Perdón aquí esto funciona correctamente No es que no vaya a hacer nada es decir él hace su trabajo sin ningún problema aunque no tengamos iniciada la cola y esté despachando trabajo es completamente independiente al resto de la funcionalidad de nuestra aplicación Aunque pendiente con esto porque si no la tienes activo a la final cuando la actives entonces va a empezar a procesar los trabajos que dejaste ahí anteriormente agrupados Y es otra vez por esto aunque esto lo vamos a ver más claramente en el siguiente video creo que para no alargar este dem más nos quedamos hasta acá Y esto es precisamente excelente porque de esta forma ya que es otra vez un proceso costoso puede que y es un proceso paralelo puede que en algún punto a al desarrollador o al que esté gestionando aquí el servidor se le haya olvidado de detectar de que bueno precisamente la cola Aquí está caída y no esté funcionando pero aún así punto importante no da error en la aplicación y punto que también es importante esos trabajos que están aquí despachando o es lo que se quiera que no está haciendo nada no se van a perder cuando se inicia otra vez el proceso él lo va a retomar y lo va a despachar Entonces ya con eso otra vez ganamos una tolerancia de fallos al sistema y obviamente hacemos un sistema también más robusto por lo comentado antes porque esos trabajos que son costosos no se pierden ya sea porque el sistema esté consumiendo más memoria o poder de procesamiento en un momento dado y que no puede dar y por lo tanto falla la aplicación y porque otra vez esos trabajos no se van a perder simplemente quedan encolados por la laravel Así que vamos a ejecutarlo en el en la siguiente clase para no alargar esta demás.
- Andrés Cruz
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter
Acepto recibir anuncios de interes sobre este Blog.
!Cursos desde!
10$
En Udemy
Quedan 4d 18:36!
!Cursos desde!
4$
En Academia
Ver los cursos!Libros desde!
1$
Ver los libros