zer*_*nes 50 crontab laravel artisan
我最近设置了一个Laravel Queue系统.基础是cronjob调用一个命令,它将作业添加到队列中并调用第二个发送电子邮件的命令.
当我进入我的服务器并运行php artisan队列时,系统工作:listen,但是如果我关闭我的终端,则监听器关闭,作业堆叠起来并排队,直到我重新进入并再次运行监听.
什么是让我的队列系统在后台运行而不需要通过ssh保持我的连接打开的最佳方法?
我尝试运行php artisan queue:work --daemon,它完成了队列中的作业,但当我关闭终端时,它关闭了连接和后台进程.
Ben*_*rne 60
运行
nohup php artisan queue:work --daemon &
Run Code Online (Sandbox Code Playgroud)
注销时会阻止命令退出.
尾随&符号(&)导致进程在后台启动,因此您可以继续使用shell,而不必等到脚本完成.
nohup - 运行一个免于挂断的命令,输出为非tty
这将把信息输出到运行命令的目录中名为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 &
Run Code Online (Sandbox Code Playgroud)
但是你也应该使用像Supervisord这样的东西来确保服务保持运行并在崩溃/失败后重新启动.
Man*_*kar 22
你应该使用linux supervisor
安装很简单,在Ubuntu上我可以使用以下命令安装它:
apt-get install supervisor
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
对于每个进程,您应该创建一个新的进程配置文件.使用此配置,侦听器将重试每个作业3次.如果监听程序失败或系统重新启动,Supervisor也会重新启动监听程序.
zer*_*nes 12
命令
nohup php artisan queue:work --daemon &
Run Code Online (Sandbox Code Playgroud)
是正确的,它将允许进程在关闭SSH连接后继续; 但是,这只是一个短期的解决方案.重新启动服务器或任何问题导致进程停止后,您将需要返回并再次运行该命令.当发生这种情况时,你永远不知道.它可能发生在星期五晚上,因此最好实施长期解决方案.
我最终切换到Supervisord,这可以安装在Ubuntu上一样简单
sudo apt-get install supervisor
Run Code Online (Sandbox Code Playgroud)
对于AWS-AMI或RedHat用户,您可以按照我在此问题中列出的说明进行操作:
在AWS AMI Linux服务器上设置Supervisord
安装主管
sudo apt-get install supervisor
Run Code Online (Sandbox Code Playgroud)
配置主管
第 1 步:转到/etc/supervisor/conf.d目录
cd /etc/supervisor/conf.d
Run Code Online (Sandbox Code Playgroud)
第 2 步:创建一个将侦听队列的工作文件laravel-worker.conf
sudo nano laravel-worker.conf
Run Code Online (Sandbox Code Playgroud)
*注意:现在假设您的 Laravel 应用程序在/var/www/html目录中
project folder is : /var/www/html/LaravelApp
Run Code Online (Sandbox Code Playgroud)
第 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
Run Code Online (Sandbox Code Playgroud)
*注意:这里假设您使用redis进行队列连接
在 .env 文件中 QUEUE_CONNECTION=redis
command=php /var/www/html/LaravelApp/artisan queue:listen redis
Run Code Online (Sandbox Code Playgroud)
如果您使用其他连接,则一般语法为:
command= php [project_folder_path]/artisan queue:listen [connection_name]
Run Code Online (Sandbox Code Playgroud)
[connection_name] 可以是sync、database、beanstalkd、sqs、redis 中的任何一个
第 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
Run Code Online (Sandbox Code Playgroud)
第 5 步:启动主管:运行以下命令
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start all
Run Code Online (Sandbox Code Playgroud)
*注意:每当您对任何配置.conf文件进行更改时,请运行上述步骤 5 的命令
额外有用的信息:
sudo supervisorctl stop allsudo supervisorctl restart all有用的链接:
https://laravel.com/docs/5.8/queues#running-the-queue-worker
http://supervisord.org/index.html
来自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;
}
}
Run Code Online (Sandbox Code Playgroud)
对于那些已经在他们的生产环境中运行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
Run Code Online (Sandbox Code Playgroud)
我在开发和设置 NodeJS 中使用 Vagrant,这个过程只使用内联 vagrant 脚本。
当您在开发中使用 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
Run Code Online (Sandbox Code Playgroud)
1)sudo apt install supervisor 或
sudo apt-get install supervisor
Run Code Online (Sandbox Code Playgroud)
2)cd /etc/supervisor/conf.d
3)在内部创建新文件
sudo vim queue-worker.conf
Run Code Online (Sandbox Code Playgroud)
文件内容
[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
Run Code Online (Sandbox Code Playgroud)
4)sudo supervisorctl reread
运行此命令时获取输出queue-worker:available
5)sudo supervisorctl update
运行此命令时,获取输出queue-worker:added进程组
其他命令
1)sudo supervisorctl reload
运行此命令时获取输出重新启动主管
2)sudo service supervisor restart
我使用pm2(高级,Node.js 的生产流程管理器)运行 JS 脚本,这是我唯一运行的脚本。但是现在我又多了一个进程可以继续运行。
我创建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.
Run Code Online (Sandbox Code Playgroud)
现在运行:
> sudo pm2 start process.yml
Run Code Online (Sandbox Code Playgroud)
由于这是一个特定于 Laravel 的问题,我想我会建议一个特定于 Lravel 的答案。由于您已经在此服务器上使用 cronjobs,因此我建议您将 shell 命令设置为重复的 cronjob,以始终验证工作线程是否正在运行。您可以将 shell 命令设置为通过服务器上的 cron 本地运行,也可以使用 Laravel 控制台内核来管理命令并添加逻辑,例如检查是否已经有一个工作线程在运行,如果没有,则继续并重新启动它。
根据您需要运行命令的频率,您可以每周执行一次,甚至每分钟一次。这将使您能够确保您的工作人员持续运行,而无需向您的服务器(例如 Supervisor)添加任何开销。如果您信任它,向像主管这样的第 3 方包授予权限是可以的,但是如果您可以避免需要依赖它,您可能需要考虑这种方法。
使用它来执行您想要的操作的一个示例是每小时运行一个 cronjob。它将从自定义 Laravel 控制台命令中按顺序执行以下命令:
\Artisan::call('队列:重新启动');
\Artisan::call('队列:工作 --daemon');
请注意,这适用于较旧版本的 Laravel(最高 5.3),但我尚未在较新版本上进行测试。
小智 5
最好的方法是 PM2(高级,Node.js 的生产流程管理器),您可以监控您的队列并查看它们的日志。
在您的项目目录中使用以下命令,运行 queue worker :
pm2 start artisan --name laravel-worker --interpreter php -- queue:work --daemon
Run Code Online (Sandbox Code Playgroud)
对于使用systemd作为初始化服务的系统,您可以使用以下服务,使其适应您的项目(在 /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
Run Code Online (Sandbox Code Playgroud)
重新加载配置并在启动时启用它:
[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
Run Code Online (Sandbox Code Playgroud)
根据您的环境及其配置功能,有多种方法可以给这只猫剥皮。有些位于共享主机上,有些具有whm访问权限......
更直接和可维护的方式是:
在你的内核文件中添加$schedule->command('queue:work')->everyFiveMinutes()->withoutOverlapping();到您的计划方法。
这将每五分钟运行一次队列工作命令。
/**
* Define the application's command schedule.
*
* @param Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('queue:work')->everyFiveMinutes()->withoutOverlapping();
}
Run Code Online (Sandbox Code Playgroud)
请参阅 laravel 文档 - https://laravel.com/docs/9.x/scheduling#defining-schedules
| 归档时间: |
|
| 查看次数: |
48262 次 |
| 最近记录: |