&引用;“最佳方式”;要运行Laravel队列,请侦听
目前,我正在做一个项目,在这个项目中,我将发送的电子邮件排成队列。但是,我想知道运行队列侦听器的“最佳方式”是什么。现在我只知道nohup的方式 但是,通过使用&引用;“最佳方式”;要运行Laravel队列,请侦听,laravel,queue,listener,Laravel,Queue,Listener,目前,我正在做一个项目,在这个项目中,我将发送的电子邮件排成队列。但是,我想知道运行队列侦听器的“最佳方式”是什么。现在我只知道nohup的方式 但是,通过使用nohup,感觉队列侦听器不再是应用程序的一部分。这就像使用调度程序使cronjobs成为应用程序的一部分 有没有其他方法来倾听队列的声音?您的偏好是什么?以下是我为实现这一点所写的内容: app/Console/Commands/QueueProcessListener.php <?php namespace App\Conso
nohup
,感觉队列侦听器不再是应用程序的一部分。这就像使用调度程序使cronjobs成为应用程序的一部分
有没有其他方法来倾听队列的声音?您的偏好是什么?以下是我为实现这一点所写的内容: app/Console/Commands/QueueProcessListener.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class QueueProcessListener extends Command
{
/**
* The name of the command/process we want to monitor. This string will be used both to check to see if the process
* is currently running and to spawn it (The arguments are appended to it).
*
* @var string
*/
protected $command = 'php artisan queue:listen';
/**
* The arguments to pass to the process when spawning it.
*
* @var string
*/
protected $arguments = '--tries=3';
/**
* The signature of the console command. We use the signature when running it through Artisan: php artisan $signature
*
* @var string
*/
protected $signature = 'queue-process-listener';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Monitor the queue listener process to ensure it is always running.';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
if (!$this->isProcessRunning($this->command)) {
$this->info("Starting queue listener.");
$this->executeShellCommand($this->command, $this->arguments, true);
} else {
$this->info("Queue listener is running.");
}
}
/**
* Execute a shell command, with the provided arguments, and optionally in the background. Commands that are not run
* in the background will return their output/response.
*
* @param $command
* @param string $arguments
* @param bool $background
* @return string
*/
public function executeShellCommand($command, $arguments = '', $background = false)
{
$command = trim($command);
if (!is_string($command) || empty($command)) {
return null;
}
$arguments = trim($arguments);
$cmd = trim($command . ' ' . $arguments) . ($background ? ' > /dev/null 2>/dev/null &' : '');
return shell_exec($cmd);
}
/**
* Check if a process is running using pgrep.
*
* @param $process
* @return bool
*/
public function isProcessRunning($process)
{
$output = $this->executeShellCommand('pgrep -f "' . $process . '"');
return !empty(trim($output));
}
}
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
Commands\QueueProcessListener::class
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// Schedule my process listener to run every 5 minutes.
$schedule->command('queue-process-listener')->everyFiveMinutes();
}
}
以下是我为实现这一目标而编写的内容:
app/Console/Commands/QueueProcessListener.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class QueueProcessListener extends Command
{
/**
* The name of the command/process we want to monitor. This string will be used both to check to see if the process
* is currently running and to spawn it (The arguments are appended to it).
*
* @var string
*/
protected $command = 'php artisan queue:listen';
/**
* The arguments to pass to the process when spawning it.
*
* @var string
*/
protected $arguments = '--tries=3';
/**
* The signature of the console command. We use the signature when running it through Artisan: php artisan $signature
*
* @var string
*/
protected $signature = 'queue-process-listener';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Monitor the queue listener process to ensure it is always running.';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
if (!$this->isProcessRunning($this->command)) {
$this->info("Starting queue listener.");
$this->executeShellCommand($this->command, $this->arguments, true);
} else {
$this->info("Queue listener is running.");
}
}
/**
* Execute a shell command, with the provided arguments, and optionally in the background. Commands that are not run
* in the background will return their output/response.
*
* @param $command
* @param string $arguments
* @param bool $background
* @return string
*/
public function executeShellCommand($command, $arguments = '', $background = false)
{
$command = trim($command);
if (!is_string($command) || empty($command)) {
return null;
}
$arguments = trim($arguments);
$cmd = trim($command . ' ' . $arguments) . ($background ? ' > /dev/null 2>/dev/null &' : '');
return shell_exec($cmd);
}
/**
* Check if a process is running using pgrep.
*
* @param $process
* @return bool
*/
public function isProcessRunning($process)
{
$output = $this->executeShellCommand('pgrep -f "' . $process . '"');
return !empty(trim($output));
}
}
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
Commands\QueueProcessListener::class
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// Schedule my process listener to run every 5 minutes.
$schedule->command('queue-process-listener')->everyFiveMinutes();
}
}
该文档准确地告诉您如何实现这一点:
我不知道你说的不是“应用程序的一部分”是什么意思。cron和后台工作进程是任何规模服务器体系结构的标准部分。使用它们没有什么错
你也应该真正避免做乔纳森的回答所建议的事情,这基本上就是用php编写你自己的supervisords
。如果服务器重新启动怎么办?对于这个问题,有一些经过战斗测试的解决方案,linux社区已经开发和支持了很长一段时间,您应该真正使用它们。文档确切地告诉您如何实现这一点:
我不知道你说的不是“应用程序的一部分”是什么意思。cron和后台工作进程是任何规模服务器体系结构的标准部分。使用它们没有什么错
你也应该真正避免做乔纳森的回答所建议的事情,这基本上就是用php编写你自己的supervisords
。如果服务器重新启动怎么办?对于这个问题,有一些经过战斗测试的解决方案,linux社区已经开发和支持了很长一段时间,您应该真正使用它们。我通过编写一个进程侦听器类型的任务来实现这一点,我计划每分钟运行一次。这样做的目的是使用pgrep
检查队列是否正在运行,如果发现队列没有运行,则启动它。@Jonathon执行类似于cronjob中的任务?我脑子里也有这样的想法,加入了queue:listen
到我的laravel日程表中,每天运行,但加入而不重叠()。它应该是这样的:$schedule->command('queue:listen')->daily()->withoutOverlapping()是的,我创建了控制台命令App\console\Commands\QueueProcessListener
。然后我将它添加到Kernel.php
以使Artisan能够使用它,并最终将它添加到内核的schedule
方法中,以使它每5分钟运行一次:$schedule->command('queue-process-listener')->everyFiveMinutes()代码>查看我的答案了解我是如何实现itAn的监视队列的替代方法使用的-如果队列因任何原因停止(免责声明:我的站点),这将提醒您我是通过编写一个进程侦听器类型的任务实现的,我计划每分钟运行一次。这样做的目的是使用pgrep
检查队列是否正在运行,如果发现队列没有运行,则启动它。@Jonathon执行类似于cronjob中的任务?我脑子里也有这样的想法,加入了queue:listen
到我的laravel日程表中,每天运行,但加入而不重叠()。它应该是这样的:$schedule->command('queue:listen')->daily()->withoutOverlapping()是的,我创建了控制台命令App\console\Commands\QueueProcessListener
。然后我将它添加到Kernel.php
以使Artisan能够使用它,并最终将它添加到内核的schedule
方法中,以使它每5分钟运行一次:$schedule->command('queue-process-listener')->everyFiveMinutes()代码>查看我的答案,了解我是如何实现itAn的,它是监视队列使用的替代方案-如果队列因任何原因停止(免责声明:我的站点)将向您发出警告谢谢,我想我会按照您所说的做。不是$schedule->command('queue:listen')->daily()->没有重叠吗ing()
还不够吗?因为它已经是一个可以调用和执行的命令。酷。这样做的问题是,如果队列侦听器由于某种原因在一天中停止,它将在第二天之前不会再次启动。另一方面,如果它在白天不停止,您就有运行多个队列侦听器的风险(如果您在后台使用nohup
或&
等启动该命令)。如果您正在直接运行队列:listen
命令,它将无法及时完成执行,从而让您计划的其他命令也运行-因此您将有效地阻止计划程序。感谢您的响应。忘记daily()
或everyMinute()
。通过使用而不使用重叠ping()
您阻止它在仍在运行时执行,对吗?或者您是说,即使没有重叠,调度程序也会对这些命令进行排队/堆叠ing()
用于在完成上一步后执行?你是说调度程序不是异步的(一次不能执行多个)?是的,withoutOverlapping()
将阻止调度程序中的命令相互重叠,而不是命令php artisan queue:listen
。如果计划作业最终执行php artisan queue:listen&
(或使用nohup
),则计划作业将正常完成。但是,下一次计划运行该命令时,它将生成一个新的php artisan队列实例:listen&
。如果没有重叠,则只会停止Laravel命令的重叠,而不会停止它产生的进程。另一方面,如果同步启动命令并最终运行<代码>php artisan队列:侦听
。那么命令将永远不会结束,t