Laravel nos proveé una herramienta que son las colas o queues que nos permiten ejecutar procesos, que hacen que nuestra aplicación se ralentice, en background. Es decir, nos permite ponerlos en una cola de procesos y que se vayan ejecutando en background según van entrando a la cola, uno a uno. Así, al ejecutarse en background, se evita que nuestra aplicación se vea afectada, porque los procesos se ejecutarán por debajo, mientras nuestra aplicación continua con su ejecución.
Una vez entendemos para que sirven las colas, vamos a ver cómo aplicarlas al envío de mails.
Creamos el email:
1 |
php artisan make:mail TestEmail |
Ejecutando este comando, Laravel nos creará en app/Mail un fichero TestMail.php que será el mail de prueba que vamos a utilizar para el ejemplo. Lo abrimos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Queue\ShouldQueue; class TestEmail extends Mailable { use Queueable, SerializesModels; /** * Build the message. * * @return $this */ public function build() { return $this->view('mails.test-mail'); } } |
Creamos la vista del mail en resources/views/mails/test-mail.blade.php:
1 |
Esto es un mail de prueba. |
Como es un email de prueba, yo he puesto esto, pero podrías poner lo que quieras.
Una vez ya tenemos el email, tendremos que configurar el server de envío de correos. Yo lo tengo configurado con Mailtrap.io, pero lo podrías configurar con MailHog o cualquier otro servicio. Puedes echar un vistazo a esta entrada del blog para ver cómo hacerlo.
Ahora vamos a configurar las colas. Laravel nos proveé varios drivers para las colas. Algunos de ellos son Redis, sync, base de datos, entre otros. Para ver los diferentes drivers y sus configuraciones, puedes ir al archivo config/queue.php.
Yo voy a utilizar el driver de base de datos. Para ello, vamos al archivo .env y añadimos o modificamos la siguiente línea:
1 |
QUEUE_CONNECTION=database |
Tenemos que tener una tabla en la base de datos donde guardar los registros de la cola, para que los procesos se vayan completando uno a uno. Laravel tiene un comando que nos genera la migración de la tabla para las colas por nosotros:
1 2 |
php artisan queue:table php artisan migrate |
Cuando ejecutemos la migración, nos creará una tabla en la base de datos llamada jobs, dónde se guardarán los registros de la cola.
Ya tenemos configuradas las colas. Ahora, lo que tenemos que hacer es enviar el mail creado anteriormente. Pero el proceso será que se añada la cola y luego se envíe, en vez de enviarlo directamente.
Vamos al controlador y añadimos lo siguiente:
1 2 3 4 5 6 |
use App\Mail\TestMail; ... Mail::to($request->user()) ->queue(new TestMail()); ... |
Vamos a la ruta del controlador y si vamos a ver los registros de la tabla jobs, veremos que se ha añadido un registro pero que no se ha procesado. Para procesarlo, deberemos ejecutar otro comando de Laravel:
1 |
php artisan queue:work |
Podríamos configurar el número de veces que queremos que intente ejecutar un proceso añadiendo la opción –tries=[número de veces], el número de segundo que puede ejecutarse un proces con la opción –timeout=[número de segundos], entre otras opciones.
Si queremos ejecutar el comando anterior en background, lo podemos hacer con Supervisor que es un gestor de procesos para Linux. Para ello, lo primero que vamos a hacer va a ser instalarlo:
1 |
sudo apt-get install supervisor |
Cuando finalice la instalación, creamos un archivo en /etc/supervisor/conf.d/ con el nombre que quieras, pero tiene que tener la extensión .conf. Yo lo he llamado test-queue.conf y le añadimos lo siguiente:
1 2 3 4 5 6 7 8 9 |
[program:test-queue] process_name=%(program_name)s_%(process_num)02d command=php /var/www/artisan queue:work --tries=3 autostart=true autorestart=true user=root numprocs=8 redirect_stderr=true stdout_logfile=/var/www/storage/logs/test-queue.log |
Tendrás que cambiar las rutas para que funcione en tu sistema y los nombres también.
Arrancamos Supervisor y ya debería ejecutar el comando de Laravel para procesar las colas sin preocuparnos.
1 |
sudo service supervisor start |
Para ver si se está ejecutando correctamente, podemos ejecutar el siguiente comando:
1 |
supervisorctl status |
Este comando nos devolverá los procesos que se están ejecutando por Supervisor, su estado y el tiempo que lleva ejecutándose:
1 |
test-queue:test-queue_00 RUNNING pid 66, uptime 0:01:44 |
Para comprobar que funciona correctamente, vamos a la ruta y vemos si se procesan las colas. Si se procesa todo correctamente debería llegar el correo, sin tener que ejecutar el comando manualmente.
-