Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;“最佳方式”;要运行Laravel队列,请侦听_Laravel_Queue_Listener - Fatal编程技术网

&引用;“最佳方式”;要运行Laravel队列,请侦听

&引用;“最佳方式”;要运行Laravel队列,请侦听,laravel,queue,listener,Laravel,Queue,Listener,目前,我正在做一个项目,在这个项目中,我将发送的电子邮件排成队列。但是,我想知道运行队列侦听器的“最佳方式”是什么。现在我只知道nohup的方式 但是,通过使用nohup,感觉队列侦听器不再是应用程序的一部分。这就像使用调度程序使cronjobs成为应用程序的一部分 有没有其他方法来倾听队列的声音?您的偏好是什么?以下是我为实现这一点所写的内容: app/Console/Commands/QueueProcessListener.php <?php namespace App\Conso

目前,我正在做一个项目,在这个项目中,我将发送的电子邮件排成队列。但是,我想知道运行队列侦听器的“最佳方式”是什么。现在我只知道nohup的方式

但是,通过使用
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()
。通过使用
而不使用重叠p‌​‌​ing()
您阻止它在仍在运行时执行,对吗?或者您是说,即使
没有重叠,调度程序也会对这些命令进行排队/堆叠‌​‌​ing()
用于在完成上一步后执行?你是说调度程序不是异步的(一次不能执行多个)?是的,
withoutOverlapping()
将阻止调度程序中的命令相互重叠,而不是命令
php artisan queue:listen
。如果计划作业最终执行
php artisan queue:listen&
(或使用
nohup
),则计划作业将正常完成。但是,下一次计划运行该命令时,它将生成一个新的
php artisan队列实例:listen&
。如果没有重叠,则只会停止Laravel命令的重叠,而不会停止它产生的进程。另一方面,如果同步启动命令并最终运行<代码>php artisan队列:侦听
。那么命令将永远不会结束,t