How to keep Laravel Queue system running on server

后端 未结 17 950
小鲜肉
小鲜肉 2020-11-28 02:23

I recently setup a Laravel Queue system. The basics are a cronjob calls a command which adds jobs to a queue and calls a second command which sends an email.

The sy

相关标签:
17条回答
  • 2020-11-28 03:15

    I achieved the result without any service monitor or third party software. The solution is working fine but I am not sure if it is the best way.

    Solution

    Just run cli command in the following way in your function.

    use Illuminate\Console\Command;
    
    public function callQueue()
    {
            $restart = 'php-cli ' . base_path() . '/artisan queue:restart > /dev/null & echo $!'; 
            $work = 'php-cli ' . base_path() . '/artisan queue:work --timeout=0 --sleep=5 --tries=3 > /dev/null & echo $!';
            exec($restart);
            exec($work);
    }
    
    $job = (new jobName())->delay(Carbon::now()->addSeconds(5));
    dispatch($job);
    

    Reason

    The reason I have used these two commands is because the command associated with $restart prevent having any memory issue according to a comment in this answer and the command associated with $work ensures that the command is successfully executed before the job.

    0 讨论(0)
  • 2020-11-28 03:17

    The command

    nohup php artisan queue:work --daemon &
    

    was correct, it would allow the process to continue after closing the SSH connection; however, this is only a short term fix. Once your server is rebooted or any issue causes the process to stop you will need to go back and run the command again. When that occurs, you never know. It could happen on a Friday night, so it is better to implement a long term solution.

    I ended up switching over to Supervisord, this can be installed on Ubuntu as easy as

    sudo apt-get install supervisor 
    

    For AWS-AMI or RedHat users you can follow the set of instructions I outlined in this question:

    Setting up Supervisord on a AWS AMI Linux Server

    0 讨论(0)
  • 2020-11-28 03:17

    What if you start the listening within a screen? See here: http://aperiodic.net/screen/quick_reference Then even if you log out, the screen would still be active and running. Not sure why the daemonization doesnt work though.

    0 讨论(0)
  • 2020-11-28 03:18

    From 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;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 03:19

    For systems with systemd as init service you could use the following service, adapting it to your project (create it on /etc/systemd/system/queue-handler.service):

    [Unit]
    Description = Queue Handler - Project
    After = network-online.target, mysql.service
    
    [Service]
    User = www-data
    Type = simple
    WorkingDirectory=/var/www/project
    ExecStart = /usr/bin/php /var/www/project/artisan queue:work --tries=3
    Restart = on-failure
    RestartSec=5s
    RestartPreventExitStatus = 255
    
    [Install]
    WantedBy = multi-user.target
    

    Reload the configurations and enable it on boot:

    $ systemctl enable queue-handler.service
    $ systemctl daemon-reload
    
    0 讨论(0)
提交回复
热议问题