Comment maintenir le système de file D'attente Laravel sur le serveur
j'ai récemment mis en place un système de file D'attente Laravel. Les bases sont une cronjob appelle une commande qui ajoute des jobs à une file d'attente et appelle une seconde commande qui envoie un email.
le système fonctionne lorsque je ssh sur mon serveur et exécute php artisan queue:listen, mais si je ferme mon terminal l'écouteur se ferme et les travaux empilent et s'assoient dans la file d'attente jusqu'à ce que je ssh de retour et exécuter listen again.
Quelle est la meilleure façon de garder mon système de file d'attente contexte sans avoir besoin de garder ma connexion ouverte via ssh?
j'ai essayé d'exécuter php artisan queue:work --daemon
, et il a complété les travaux dans la file d'attente, mais quand j'ai fermé mon terminal il a fermé la connexion et le processus de fond.
9 réponses
Running
nohup php artisan queue:work --daemon &
empêchera la commande de quitter lorsque vous vous déconnecterez.
l'ampli arrière-plan ampersand (&) provoque le démarrage du processus en arrière-plan, vous pouvez donc continuer à utiliser le shell et ne pas avoir à attendre que le script soit terminé.
voir nohup
nohup-exécuter une commande à l'abri de raccroches, avec une sortie à un non-tty
ceci produira des informations dans un fichier intitulé nohup.dans le répertoire où vous exécutez la commande. Si vous n'avez aucun intérêt dans la sortie, vous pouvez rediriger stdout et stderr vers /dev/null, ou de la même manière, vous pouvez la sortir dans votre log laravel normal. Par exemple
nohup php artisan queue:work --daemon > /dev/null 2>&1 &
nohup php artisan queue:work --daemon > app/storage/logs/laravel.log &
mais vous devez également utiliser quelque chose comme Supervisord pour s'assurer que le service reste en cours d'exécution et est redémarré après des accidents/défaillances.
Vous devez utiliser linux superviseur
Installation est simple et sur Ubuntu je peux l'installer avec la commande suivante:
apt-get install supervisor
Les fichiers de configuration des superviseurs se trouvent dans le fichier /etc/supervisor/conf.d répertoire.
[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
pour chaque processus, vous devez créer un nouveau fichier de configuration de processus. Avec cette configuration, l'auditeur va réessayer chaque tâche 3 fois. Également Superviseur redémarrez écoute si elle échoue ou si le système redémarre.
la commande
nohup php artisan queue:work --daemon &
était correct, il permettrait au processus de continuer après la fermeture de la connexion SSH; cependant, ce n'est qu'une solution à court terme. Une fois que votre serveur est redémarré ou que n'importe quel problème provoque l'arrêt du processus, vous devrez revenir en arrière et exécuter la commande à nouveau. Lorsque cela se produit, vous ne savez jamais. Cela pourrait se produire un vendredi soir, il est donc préférable de mettre en œuvre une solution à long terme.
j'ai fini par passer à Supervisord, cela peut être installé sur Ubuntu aussi facile que
sudo apt-get install supervisor
pour les utilisateurs AWS-AMI ou RedHat, vous pouvez suivre les instructions que j'ai indiquées dans cette question:
si vous commencez à l'écoute à l'intérieur d'un écran? Voir ici: http://aperiodic.net/screen/quick_reference Alors même si vous vous déconnectez, l'écran sera toujours actif et en cours d'exécution. Je ne sais pas pourquoi la démonisation ne fonctionne pas.
pour ceux qui exécutent déjà NodeJS sur leurs environnements de production. J'utilise les PM2 pour gérer les processus app.
# 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
J'utilise Vagrant dans le développement et la configuration de NodeJS et ce processus en utilisant seulement des scripts vagrant en ligne.
quand vous utilisez PM2 dans le développement, vous pouvez utiliser l'un des nombreux observateurs pour gérer le redémarrage. Il suffit d'exécuter pm2 restart queue-worker
lorsque vous recevez un changement. En production Je ne recommande pas ceci approche, optez plutôt pour un outil de construction qui peut suivre ce processus.
# 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
Puisqu'il s'agissait d'une question spécifique à Laravel, j'ai pensé que je suggérerais une réponse spécifique à Lravel. Puisque vous utilisez déjà cronjobs sur ce serveur, je vous recommande de configurer la commande shell comme une cronjob récurrente pour toujours vérifier que le worker est en cours d'exécution. Vous pouvez configurer la commande shell pour qu'elle soit exécutée nativement par cron sur votre serveur, ou vous pouvez utiliser le noyau de la console Laravel pour gérer la commande et ajouter de la logique, comme vérifier si vous avez déjà une travailleur courant et, si ce n'est pas le cas, recommencez-le.
selon la fréquence à laquelle vous devez exécuter votre commande, vous pouvez le faire aussi rarement qu'une fois par semaine, ou même une fois par minute. Cela vous donnerait la possibilité de vous assurer que vos employés fonctionnent en permanence, sans avoir à ajouter de frais généraux à votre serveur, tel que le superviseur. Donner des permissions à un paquet tiers comme supervisor est ok si vous lui faites confiance, mais si vous pouvez éviter d'avoir à compter sur lui, vous souhaitez peut-être envisager cette approche à la place.
un exemple d'utilisation de ceci pour faire ce que vous voulez serait d'avoir un cronjob qui court chaque heure. Il exécuterait ce qui suit dans l'ordre séquentiel à partir d'une commande personnalisée de la console Laravel:
\Artisan::appelez le('file d'attente:restart');
\Artisan:: call ('file:work --daemon');
notez que ceci s'applique pour les versions plus anciennes de Laravel (jusqu'à 5.3) mais je n'ai pas testé sur des versions plus récentes.
de 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;
}
}
vous pouvez utiliser monit outil. il est très petit et utile pour tout type de processus de gestion et de suivi.
après avoir téléchargé le paquet binaire à partir de ce lien , vous pouvez l'extraire à un dossier sur votre système et ensuite copier deux fichiers du paquet à votre système pour l'installer:
cd /path/to/monit/folder
cp ./bin/monit /usr/sbin/monit
cp ./conf/monitrc /etc/monitrc
maintenant éditer /etc/monitrc
base sur vos besoins ( doc de référence ). puis créer un fichier de contrôle d'entrée pour activer monit au démarrage. maintenant commence monit comme ceci:
initctl reload-configuration
start monit
utilisant pm2
j'ai fait tourner le script JS avec pm2 (avancé, responsable du processus de production pour Node.js) qui était la seule que je courais. Mais maintenant que j'en ai un plus pour le garder en cours d'exécution.
j'ai créé process.yml
pour exécuter les deux avec une seule commande.
Vérifiez que le premier serait 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.
exécuter:
> sudo pm2 start process.yml