如何让 Laravel Queue 系统在服务器上运行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28623001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 16:53:32  来源:igfitidea点击:

How to keep Laravel Queue system running on server

laravelcrontabartisan

提问by zeros-and-ones

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.

我最近设置了一个 Laravel 队列系统。基础是一个 cronjob 调用一个命令,将作业添加到队列中,并调用发送电子邮件的第二个命令。

The system works when I ssh into my server and run php artisan queue:listen, but if I close my terminal the listener shuts down and the jobs stack up and sit in queue until I ssh back in and run listen again.

当我 ssh 进入我的服务器并运行 php artisan queue:listen 时,系统工作,但如果我关闭我的终端,监听器将关闭,作业堆积并排入队列,直到我重新进入并再次运行监听。

What is the best way to keep my queue system running in the background without needing to keep my connection open via ssh?

让我的队列系统在后台运行而不需要通过 ssh 保持连接打开的最佳方法是什么?

I tried running php artisan queue:work --daemon, and it completed the jobs in the queue, but when I closed my terminal it closed the connection and the background process.

我尝试运行php artisan queue:work --daemon,它完成了队列中的作业,但是当我关闭终端时,它关闭了连接和后台进程。

回答by Ben Swinburne

Running

跑步

nohup php artisan queue:work --daemon &

Will prevent the command exiting when you log out.

当您注销时,将阻止命令退出。

The trailing ampersand (&) causes process start in the background, so you can continue to use the shell and do not have to wait until the script is finished.

尾随符号 (&) 导致进程在后台启动,因此您可以继续使用 shell,而不必等到脚本完成。

See nohup

查看nohup

nohup - run a command immune to hangups, with output to a non-tty

nohup - 运行一个不受挂断影响的命令,输出到非 tty

This will output information to a file entitled nohup.out in the directory where you run the command. If you have no interest in the output you can redirect stdout and stderr to /dev/null, or similarly you could output it into your normal laravel log. For example

这会将信息输出到您运行命令的目录中名为 nohup.out 的文件中。如果您对输出不感兴趣,您可以将 stdout 和 stderr 重定向到 /dev/null,或者类似地,您可以将其输出到您的普通 Laravel 日志中。例如

nohup php artisan queue:work --daemon > /dev/null 2>&1 &

nohup php artisan queue:work --daemon > app/storage/logs/laravel.log &

But you should also use something like Supervisordto ensure that the service remains running and is restarted after crashes/failures.

但是你也应该使用像Supervisord这样的东西来确保服务保持运行并在崩溃/失败后重新启动。

回答by Manish Nakar

You should use linux supervisor

你应该使用 linux主管

Installation is simple and on Ubuntu I can install it with following command:

安装很简单,在 Ubuntu 上我可以使用以下命令安装它:

apt-get install supervisor

Supervisor configuration files are located in /etc/supervisor/conf.d directory.

Supervisor 配置文件位于 /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

For each process you should create a new process configuration file. With this configuration, listener will retry each job 3 times. Also Supervisor will restart listener if it fails or if system restarts.

对于每个进程,您应该创建一个新的进程配置文件。使用此配置,侦听器将重试每个作业 3 次。如果失败或系统重新启动,Supervisor 也会重新启动侦听器。

回答by zeros-and-ones

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.

是正确的,它会在关闭 SSH 连接后允许进程继续;然而,这只是短期修复。一旦您的服务器重新启动或任何问题导致进程停止,您将需要返回并再次运行该命令。当这种情况发生时,你永远不知道。它可能发生在星期五晚上,因此最好实施长期解决方案。

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

我最终切换到 Supervisord,这可以像安装在 Ubuntu 上一样简单

sudo apt-get install supervisor 

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

对于 AWS-AMI 或 RedHat 用户,您可以按照我在此问题中概述的一组说明进行操作:

Setting up Supervisord on a AWS AMI Linux Server

在 AWS AMI Linux 服务器上设置 Supervisord

回答by Harry Bosh

From https://gist.github.com/ivanvermeyen/b72061c5d70c61e86875

来自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;
    }
}

回答by Lalit Baghel

1)sudo apt install supervisoror

1)sudo apt install supervisor

sudo apt-get install supervisor

2)cd /etc/supervisor/conf.d3)create new file inside

2)cd /etc/supervisor/conf.d3)在里面创建新文件

sudo vim queue-worker.conf

File Content

文件内容

[program:email-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/laravelproject/artisan queue:work
autostart=true
autorestart=true
user=root
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/html/laravelproject/storage/logs/supervisord.log

4)sudo supervisorctl reread

4)sudo supervisorctl reread

when run this command get output queue-worker:available

运行此命令时获取输出 queue-worker:available

5)sudo supervisorctl update

5)sudo supervisorctl update

when run this command get output queue-worker:added process group

运行此命令时获取输出 queue-worker: added process group

other command

其他命令

1)sudo supervisorctl reload

1)sudo supervisorctl reload

when run this command get output Restarted supervisord

运行此命令时获取输出 Restarted supervisord

2)sudo service supervisor restart

2)sudo service supervisor restart

回答by eResourcesInc

Since this was a Laravel-specific question, I thought I would suggest a Lravel-specific answer. Since you are already using cronjobs on this server, I would recommend that you set up the shell command as a recurring cronjob to always verify that the worker is running. You could either set up the shell command to run natively through cron on your server, or you could use the Laravel console kernel to manage the command and add logic, such as checking whether you already have a worker running and, if not, go ahead and start it back up.

由于这是一个 Laravel 特定的问题,我想我会建议一个 Lravel 特定的答案。由于您已经在此服务器上使用 cronjobs,我建议您将 shell 命令设置为重复的 cronjob,以始终验证工作程序是否正在运行。您可以将 shell 命令设置为通过服务器上的 cron 本地运行,或者您可以使用 Laravel 控制台内核来管理命令并添加逻辑,例如检查您是否已经运行了一个工作程序,如果没有,请继续并重新启动它。

Depending on how often you need to run your command, you could do this as infrequently as once a week, or even once a minute. This would give you the ability to make sure that your workers are continuously running, without having to add any overhead to your server, such as Supervisor. Giving permissions to a 3rd party package like supervisor is ok if you trust it, but if you can avoid needing to rely on it, you may want to consider this approach instead.

根据您需要运行命令的频率,您可以每周执行一次,甚至每分钟执行一次。这将使您能够确保您的工作人员持续运行,而无需为您的服务器增加任何开销,例如 Supervisor。如果您信任它,则授予像 supervisor 这样的 3rd 方包的权限是可以的,但是如果您可以避免依赖它,您可能需要考虑这种方法。

An example of using this to do what you want would be to have a cronjob that runs each hour. It would execute the following in sequential order from within a custom Laravel console command:

使用它来做你想做的事情的一个例子是有一个每小时运行的 cronjob。它将从自定义 Laravel 控制台命令中按顺序执行以下操作:

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

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

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

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

Note that this applies for older versions of Laravel (up to 5.3) but I haven't tested on newer versions.

请注意,这适用于较旧版本的 Laravel(最高 5.3),但我尚未在较新版本上进行测试。

回答by faridcs

The best way is PM2 (Advanced, production process manager for Node.js) that you can monit your queues and see their's logs.

最好的方法是 PM2(高级,Node.js 的生产流程管理器),您可以监控您的队列并查看它们的日志。

with command below in your project directory, run queue worker :

在您的项目目录中使用以下命令,运行 queue worker :

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

回答by dewwwald

For those who are already running NodeJSon their production environments. I use PM2 to manage app processes.

对于那些已经在他们的生产环境中运行NodeJS 的人。我使用 PM2 来管理应用程序进程。

# 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

I use Vagrant in development and setup NodeJS and this process using only inline vagrant scripts.

我在开发和设置 NodeJS 中使用 Vagrant,这个过程只使用内联 vagrant 脚本。

When you use PM2 in development you can use one of the many watchers to manage the restart. Simply run pm2 restart queue-workerwhen you pick up a change. In production I don't recommend this approach, rather opt for a build tool that can follow this process.

当您在开发中使用 PM2 时,您可以使用众多观察者之一来管理重启。只需pm2 restart queue-worker在您选择更改时运行即可。在生产中,我不推荐这种方法,而是选择可以遵循此过程的构建工具。

# 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

回答by Saurabh Mistry

Installing Supervisor

安装主管

sudo apt-get install supervisor

Configuring Supervisor

配置主管

step 1 : goto /etc/supervisor/conf.ddirectory

第 1 步:转到/etc/supervisor/conf.d目录

cd /etc/supervisor/conf.d

step 2 : create a worker file laravel-worker.confthat will listen queue

第 2 步:创建一个将侦听队列的工作文件laravel-worker.conf

sudo nano laravel-worker.conf

*Note :Now assuming that your laravel app is inside /var/www/htmldirectory

*注意:现在假设您的 Laravel 应用程序在/var/www/html目录中

project folder is : /var/www/html/LaravelApp

step 3 : paste below code in laravel-worker.confand save file

第 3 步:将以下代码粘贴到laravel-worker.conf并保存文件

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/LaravelApp/artisan queue:listen redis --queue=default --sleep=3 --tries=3 
autostart=true
autorestart=true
user=root
numprocs=8
redirect_stderr=true
stdout_logfile= /var/www/html/LaravelApp/storage/logs/worker.log

*Note :Here is assumed that you are using redisfor queue connection

*注意:这里假设您使用redis进行队列连接

in .env file QUEUE_CONNECTION=redis

在 .env 文件中 QUEUE_CONNECTION=redis

command=php /var/www/html/LaravelApp/artisan queue:listen redis

if you are using other connection then , general syntax will be :

如果您使用其他连接,则一般语法为:

command= php [project_folder_path]/artisan queue:listen [connection_name]

[connection_name] can be any of sync, database, beanstalkd, sqs, redis

[connection_name] 可以是syncdatabasebeanstalkdsqsredis 中的任何一个

step 4 : create a worker file laravel-schedule.confthat will run artisan schedule:runcommand at every 1 minute (60 seconds)(*you can change it as per your requirement)

第 4 步:创建一个工作文件laravel-schedule.conf,它将每 1 分钟(60 秒)运行一次artisan schedule:run命令(*您可以根据需要进行更改)

[program:laravel-schedule]
process_name=%(program_name)s_%(process_num)02d
command=/bin/bash -c 'while true; do date && php /var/www/html/LaravelApp/artisan schedule:run; sleep 60; done'
autostart=true
autorestart=true
numprocs=1
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0

step 5 : Starting Supervisor : run below commands

第 5 步:启动主管:运行以下命令

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start all

*Note :Whenever you make changes in any of configuration .conffiles , run above commands of Step 5

*注意:每当您对任何配置.conf文件进行更改时,请运行上述步骤 5 的命令

Extra usefull information :

额外有用的信息:

  • to stop all supervisorctl process : sudo supervisorctl stop all
  • to restart all supervisorctl process : sudo supervisorctl restart all
  • 停止所有 supervisorctl 进程: sudo supervisorctl stop all
  • 重新启动所有 supervisorctl 进程: sudo supervisorctl restart all

usefull links :

有用的链接:

https://laravel.com/docs/5.8/queues#running-the-queue-worker

https://laravel.com/docs/5.8/queues#running-the-queue-worker

http://supervisord.org/index.html

http://supervisord.org/index.html

回答by Lahar Shah

Using pm2

使用 pm2

I had JS script running with pm2(Advanced, production process manager for Node.js) Which was the only one I was running. But now as I got one more process to keep running.

我使用pm2(高级,Node.js 的生产流程管理器)运行 JS 脚本,这是我唯一运行的脚本。但是现在我又多了一个进程可以继续运行。

I created process.ymlto run both with a single command. Check the first one would run php artisan queue: listen

我创建process.yml以使用单个命令运行两者。检查第一个会运行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.

Now run:

现在运行:

> sudo pm2 start process.yml

Check more options and feature of pm2

检查 pm2 的更多选项和功能