notificaciones - Cómo mantener el sistema Laravel Queue en el servidor
queue php (9)
Utilizando pm2
Tenía el script JS ejecutándose con pm2 (Advanced, administrador de procesos de producción para Node.js), que era el único que estaba ejecutando. Pero ahora tengo un proceso más para seguir corriendo.
process.yml
para ejecutar ambos con un solo comando. Compruebe que el primero ejecutaría la php artisan queue: listen
# process.yml at /var/www/ which is root dir of the project
apps:
# Run php artisan queue:listen to execute queue job
- script : ''artisan''
name : ''artisan-queue-listen''
cwd : ''/var/www/''
args : ''queue:listen'' # or queue:work
interpreter : ''php''
# same way add any other script if any.
Ahora ejecuta:
> sudo pm2 start process.yml
Recientemente instalé un sistema de Laravel Queue. Lo básico es que un cronjob llama a un comando que agrega trabajos a una cola y llama a un segundo comando que envía un correo electrónico.
El sistema funciona cuando ssh en mi servidor y ejecuto la cola de php artisan: listen, pero si cierro mi terminal, el oyente se apaga y los trabajos se acumulan y se ponen en cola hasta que ssh vuelva y ejecute listen de nuevo.
¿Cuál es la mejor manera de mantener mi sistema de colas funcionando en segundo plano sin necesidad de mantener mi conexión abierta a través de ssh?
Intenté ejecutar php artisan queue:work --daemon
, y php artisan queue:work --daemon
los trabajos en la cola, pero cuando cerré mi terminal cerré la conexión y el proceso en segundo plano.
¿Qué pasa si empiezas a escuchar dentro de una pantalla? Consulte aquí: http://aperiodic.net/screen/quick_reference Luego, incluso si cierra la sesión, la pantalla seguirá activa y en ejecución. Aunque no estoy seguro de por qué la demonización no funciona.
Como esta era una pregunta específica de Laravel, pensé que sugeriría una respuesta específica de Lravel. Como ya está utilizando cronjobs en este servidor, le recomendaría que configure el comando de shell como un cronjob recurrente para verificar siempre que el trabajador se está ejecutando. Puede configurar el comando de shell para que se ejecute de forma nativa a través de cron en su servidor, o puede usar el kernel de la consola Laravel para administrar el comando y agregar lógica, como verificar si ya tiene un trabajador ejecutándose y, si no, seguir adelante y volver a iniciarlo.
Dependiendo de la frecuencia con la que necesite ejecutar su comando, puede hacer esto con tan poca frecuencia como una vez a la semana, o incluso una vez por minuto. Esto le daría la posibilidad de asegurarse de que sus trabajadores estén continuamente ejecutándose, sin tener que agregar ningún gasto general a su servidor, como Supervisor. Dar permisos a un paquete de terceros como supervisor está bien si confía en él, pero si puede evitar tener que confiar en él, es posible que desee considerar este enfoque.
Un ejemplo de cómo usar esto para hacer lo que quiere es tener un cronjob que se ejecuta cada hora. Ejecutaría lo siguiente en orden secuencial desde un comando de consola Laravel personalizado:
/ Artisan :: call (''queue: restart'');
/ Artisan :: call (''queue: work --daemon'');
Tenga en cuenta que esto se aplica a versiones anteriores de Laravel (hasta 5.3), pero no he probado en versiones más recientes.
Corriendo
nohup php artisan queue:work --daemon &
Evitará que el comando salga cuando cierre la sesión.
El signo y el signo (&) final hace que el proceso se inicie en segundo plano, por lo que puede continuar utilizando el shell y no tiene que esperar hasta que finalice el script.
Ver nohup
nohup - ejecuta un comando inmune a los cuelgues, con salida a un no-tty
Esto dará salida a la información a un archivo titulado nohup.out en el directorio donde ejecuta el comando. Si no tiene interés en la salida, puede redireccionar stdout y stderr a / dev / null, o de manera similar, podría enviarlo a su registro normal de tareas. Por ejemplo
nohup php artisan queue:work --daemon > /dev/null 2>&1 &
nohup php artisan queue:work --daemon > app/storage/logs/laravel.log &
Pero también debe usar algo como Supervisord para asegurarse de que el servicio siga funcionando y se reinicie después de bloqueos / fallas.
Debes usar linux supervisor
La instalación es simple y en Ubuntu puedo instalarla con el siguiente comando:
apt-get install supervisor
Los archivos de configuración de Supervisor se encuentran en el directorio /etc/supervisor/conf.d.
[program:email-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/laravel-example/artisan queue:work redis --queue=emailqueue --sleep=3 --tries=3
autostart=true
autorestart=true
user=forge
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/laravel-example//storage/logs/supervisord.log
Para cada proceso debe crear un nuevo archivo de configuración de proceso. Con esta configuración, el oyente volverá a intentar cada trabajo 3 veces. Asimismo, Supervisor reiniciará la escucha si falla o si el sistema se reinicia.
Desde https://gist.github.com/ivanvermeyen/b72061c5d70c61e86875
<?php
namespace App/Console/Commands;
use Illuminate/Console/Command;
class EnsureQueueListenerIsRunning extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = ''queue:checkup'';
/**
* The console command description.
*
* @var string
*/
protected $description = ''Ensure that the queue listener is running.'';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
if ( ! $this->isQueueListenerRunning()) {
$this->comment(''Queue listener is being started.'');
$pid = $this->startQueueListener();
$this->saveQueueListenerPID($pid);
}
$this->comment(''Queue listener is running.'');
}
/**
* Check if the queue listener is running.
*
* @return bool
*/
private function isQueueListenerRunning()
{
if ( ! $pid = $this->getLastQueueListenerPID()) {
return false;
}
$process = exec("ps -p $pid -opid=,cmd=");
$processIsQueueListener = str_contains($process, ''queue:listen'');
return $processIsQueueListener;
}
/**
* Get any existing queue listener PID.
*
* @return bool|string
*/
private function getLastQueueListenerPID()
{
if ( ! file_exists(__DIR__ . ''/queue.pid'')) {
return false;
}
return file_get_contents(__DIR__ . ''/queue.pid'');
}
/**
* Save the queue listener PID to a file.
*
* @param $pid
*
* @return void
*/
private function saveQueueListenerPID($pid)
{
file_put_contents(__DIR__ . ''/queue.pid'', $pid);
}
/**
* Start the queue listener.
*
* @return int
*/
private function startQueueListener()
{
$command = ''php-cli '' . base_path() . ''/artisan queue:listen --timeout=60 --sleep=5 --tries=3 > /dev/null & echo $!'';
$pid = exec($command);
return $pid;
}
}
El comando
nohup php artisan queue:work --daemon &
fue correcto, permitiría que el proceso continúe después de cerrar la conexión SSH; Sin embargo, esto es sólo una solución a corto plazo. Una vez que su servidor se haya reiniciado o cualquier problema haga que el proceso se detenga, deberá volver y ejecutar el comando nuevamente. Cuando eso ocurre, nunca se sabe. Podría suceder un viernes por la noche, por lo que es mejor implementar una solución a largo plazo.
Terminé cambiando a Supervisord, esto se puede instalar en Ubuntu tan fácil como
sudo apt-get install supervisor
Para los usuarios de AWS-AMI o RedHat, puede seguir el conjunto de instrucciones que describí en esta pregunta:
Para aquellos que ya están ejecutando NodeJS en sus entornos de producción. Uso PM2 para gestionar procesos de aplicaciones.
# install
npm install -g pm2
# in project dir with your CI or dev setup tool
# --name gives task a name so that you can later manage it
# -- delimits arguments that get passed to the script
pm2 start artisan --interpreter php --name queue-worker -- queue:work --daemon
Utilizo Vagrant en el desarrollo y la configuración de NodeJS y este proceso usando solo scripts errantes en línea.
Cuando usa PM2 en desarrollo, puede usar uno de los muchos observadores para administrar el reinicio. Simplemente ejecute pm2 restart queue-worker
cuando recoja un cambio. En producción, no recomiendo este enfoque, sino que opto por una herramienta de construcción que pueda seguir este proceso.
# 1. stop pm task to ensure that no unexpected behaviour occurs during build
pm2 stop queue-worker
# 2. do your build tasks
...
# 3. restart queue so that it loads the new code
pm2 restart queue-worker
Puedes usar la herramienta monit . Es muy pequeño y útil para cualquier tipo de gestión y monitoreo de procesos.
Después de descargar el paquete binario desde este enlace , puede extraerlo en una carpeta de su sistema y luego copiar dos archivos del paquete a su sistema para instalarlo:
cd /path/to/monit/folder
cp ./bin/monit /usr/sbin/monit
cp ./conf/monitrc /etc/monitrc
Ahora edite /etc/monitrc
base en sus necesidades ( documento de referencia ). luego cree un archivo de control de inicio para habilitar monit en el inicio. ahora inicia monit como este:
initctl reload-configuration
start monit