web-dev-qa-db-fra.com

Comment garder le système Laravel Queue en marche sur le serveur

J'ai récemment installé un système Laravel Queue. Les bases sont un cronjob appelle une commande qui ajoute des travaux à une file d'attente et appelle une deuxième commande qui envoie un email. 

Le système fonctionne lorsque je ssh sur mon serveur et que j'exécute php artisan queue: écoutez, mais si je ferme mon terminal, l'écouteur s'arrête et les tâches s'empilent et restent en file d'attente jusqu'à ce que je ssh retourne et répète.

Quel est le meilleur moyen de garder mon système de files d'attente en tâche de fond sans avoir à garder ma connexion ouverte via ssh?

J'ai essayé d'exécuter php artisan queue:work --daemon et les travaux de la file d'attente étaient terminés, mais lorsque j'ai fermé mon terminal, la connexion et le processus d'arrière-plan ont été fermés.

34
zeros-and-ones

La commande 

Nohup php artisan queue:work --daemon &

était correct, cela permettrait au processus de continuer après la fermeture de la connexion SSH; Cependant, il ne s'agit que d'une solution à court terme. Une fois votre serveur redémarré ou si un problème quelconque l’arrête, vous devrez revenir en arrière et réexécuter la commande. Quand cela se produit, on ne sait 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 facilement que 

Sudo apt-get install supervisor 

Pour les utilisateurs AWS-AMI ou RedHat, vous pouvez suivre les instructions que j'ai décrites dans cette question:

Configuration de Supervisord sur un serveur AWS AMI Linux

10
zeros-and-ones

Fonctionnement 

Nohup php artisan queue:work --daemon &

Empêche la sortie de la commande lorsque vous vous déconnectez.

Le signe et commercial fin (&) provoque le démarrage du processus en arrière-plan. Vous pouvez donc continuer à utiliser le shell sans avoir à attendre la fin du script.

Voir Nohup

Nohup - Exécute une commande insensible aux blocages, avec la sortie sur un non-tty

Cela affichera les informations dans un fichier intitulé Nohup.out dans le répertoire où vous exécutez la commande. Si le résultat ne vous intéresse pas, vous pouvez rediriger stdout et stderr vers/dev/null, ou de la même manière, vous pouvez le sortir dans votre journal 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 vous assurer que le service reste en cours d’exécution et qu'il est redémarré après des pannes.

46
Ben Swinburne

Vous devriez utiliser linux supervisor

L'installation est simple et sur Ubuntu, je peux l'installer avec la commande suivante:

apt-get install supervisor

Les fichiers de configuration du superviseur se trouvent dans le répertoire /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

Pour chaque processus, vous devez créer un nouveau fichier de configuration de processus. Avec cette configuration, l’auditeur tentera à nouveau chaque travail 3 fois. Supervisor redémarrera également le programme d'écoute en cas d'échec ou de redémarrage du système.

14
Manish Nakar

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'); // 5.1
        $processIsQueueListener = ! empty($process); // 5.6 - see comments

        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 $!'; // 5.1
        $command = 'php-cli ' . base_path() . '/artisan queue:work --timeout=60 --sleep=5 --tries=3 > /dev/null & echo $!'; // 5.6 - see comments
        $pid = exec($command);

        return $pid;
    }
}
4
Harry Bosh

Pour ceux qui exécutent déjà NodeJS sur leurs environnements de production. J'utilise PM2 pour gérer les processus de l'application.

# 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 uniquement des scripts en ligne vagant.

Lorsque vous utilisez PM2 en développement, vous pouvez utiliser l'un des nombreux observateurs pour gérer le redémarrage. Exécutez simplement pm2 restart queue-worker lorsque vous prenez une modification. En production, je ne recommande pas cette approche, je préfère opter pour un outil de construction capable de 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
3
dewwwald

Et si vous démarrez l'écoute sur un écran? Voir ici: http://aperiodic.net/screen/quick_reference Même si vous vous déconnectez, l'écran reste actif et fonctionne. Vous ne savez pas pourquoi la démonisation ne fonctionne pas.

2
grasshopper

Puisqu'il s'agissait d'une question spécifique à Laravel, j'ai pensé suggérer une réponse spécifique à Lravel. Etant donné que vous utilisez déjà des tâches cron sur ce serveur, il est recommandé de configurer la commande Shell en tant que tâche récurrente afin de toujours vérifier que le poste de travail est en cours d'exécution. Vous pouvez soit configurer la commande Shell pour qu'elle s'exécute de manière native via cron sur votre serveur, soit utiliser le noyau de la console Laravel pour gérer la commande et ajouter une logique, telle que vérifier si vous avez déjà un ouvrier en cours d'exécution, sinon continuez. et le redémarrer.

Selon la fréquence à laquelle vous devez exécuter votre commande, vous pouvez le faire aussi rarement qu'une fois par semaine, voire une fois par minute. Cela vous donnerait la possibilité de vous assurer que vos travailleurs fonctionnent en continu, sans avoir à ajouter de temps système à votre serveur, tel que Supervisor. Donner des autorisations à un package tiers, tel que superviseur, est acceptable si vous y faites confiance, mais si vous pouvez éviter de devoir vous y fier, vous voudrez 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 s'exécute toutes les heures. Il exécuterait les opérations suivantes dans un ordre séquentiel depuis une commande de console Laravel personnalisée:

\ Artisan :: call ('queue: restart');

\ Artisan :: call ('queue: work --daemon');

Notez que cela s'applique aux anciennes versions de Laravel (jusqu'à la version 5.3), mais je n'ai pas testé les versions les plus récentes.

2
eResourcesInc

Utilisation de pm2

J'avais un script JS exécuté avec pm2 (Advanced, gestionnaire de processus de production pour Node.js) qui était le seul que j'exécutais. Mais maintenant, il me reste un processus à suivre. 

J'ai créé process.yml pour exécuter les deux avec une seule commande. Cochez le premier qui fonctionnerait 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.

Maintenant, lancez:

> Sudo pm2 start process.yml

Vérifiez plus d'options et la fonctionnalité de pm2

1
Lahar Shah

PM2 (Advanced, gestionnaire de processus de production pour Node.js) est le meilleur moyen de surveiller vos files d’attente et de consulter leurs journaux.

avec la commande ci-dessous dans votre répertoire de projet, exécutez le programme de traitement des files d'attente:

pm2 start artisan --name laravel-worker --interpreter php -- queue:work --daemon
1
faridcs

Vous pouvez utiliser monit tool. il est très petit et utile pour tout type de gestion et de surveillance de processus.

Après avoir téléchargé le package binaire à partir de ce lien , vous pouvez l'extraire dans un dossier de votre système, puis copier deux fichiers du package sur votre système pour l'installer: 

cd /path/to/monit/folder
cp ./bin/monit /usr/sbin/monit
cp ./conf/monitrc /etc/monitrc  

Maintenant, éditez /etc/monitrc en fonction de vos besoins ( référence doc ). puis créez un fichier de contrôle init pour activer monit au démarrage. maintenant commencer à surveiller comme ça: 

initctl reload-configuration
start monit
0
Ghasem Pahlavan

J'ai simplement utilisé php artisan queue:work --tries=3 & qui maintient le processus en arrière-plan . Mais il s'arrête parfois . Je ne sais pas pourquoi.

0
Kevin RED