在共享主机上运行 Laravel 队列:work

16

我希望在共享主机上保持我的Laravel队列程序运行,这是一台共享主机(不是VPS),因为当我搜索时,几乎所有的在线资源都建议安装Supervisor,所以我无法安装任何东西。因此,我认为我可以创建一个cron作业来检查队列是否未运行并启动它,有关如何操作的任何帮助,因为我有点困惑,谢谢。

P.S. 我在Linux服务器上,使用的是Laravel 5.3。

9个回答

18

如您所述,您正使用共享主机,按照以下步骤操作:

步骤1. 您需要将队列驱动设置为database

步骤2. 您需要设置一个定时任务,命令如下: php /path/to/application/artisan queue:work --queue=high,default

尝试一下吧,希望这能有效。


我更多地是在寻找一个解决方案,可以终止之前的命令并执行一个新的命令。 - lulliezy
有没有一种标志可以仅执行当前作业并退出,就像“— once”执行一个作业一样,类似于“— current”?我已经使用了“queue:work”,即使所有作业都已完成,它仍然会继续等待。 - lulliezy
请查看此链接:https://laravel.com/docs/5.5/queues#queue-priorities - Suresh Velusamy
2
但是这种方法消耗了大量的RAM,如何避免呢? - Ishaan
2
@Ishaan 你可能需要添加一个类似这样的标志 php artisan queue:work --queue=high,default --stop-when-empty - That's Enam
显示剩余5条评论

13

Laravel >= 5.7

在app\Console\Kernel.php的计划任务调度器中添加以下代码,并设置cron定时任务以确保队列每分钟得到服务。

$schedule->command('queue:work --stop-when-empty')
    ->everyMinute()
    ->withoutOverlapping();

对于 Cpanel 服务器,Cron 语句可能如下:

* * * * * /usr/local/bin/php /home/{account_name}/live/artisan schedule:run

{account_name}是cpanel运行的用户帐户,live是Laravel应用程序的文件夹

来源:https://talltips.novate.co.uk/laravel/using-queues-on-shared-hosting-with-laravel

Laravel <= 5.6

--once 强制工作进程在运行一个作业后退出

--tries 作业最多尝试次数

--timeout 可以指定作业运行的最大秒数

withoutOverlapping() 默认情况下,即使任务的先前实例仍在运行,也将运行计划任务。为了防止这种情况,请使用withoutOverlapping方法

sendOutputTo() 将输出发送到文件以供以后检查

$schedule->command('queue:work --timeout=60 --tries=1 --once')
    ->everyMinute()
    ->withoutOverlapping()
    ->sendOutputTo(storage_path() . '/logs/queue-jobs.log');

Laravel 所有版本

如果您不想使用“--once”或“--max-time”选项,最好使用重启命令来避免内存泄漏并应用代码更改。

$schedule->command('queue:restart')
    ->everyFiveMinutes();

Laravel <= 5.2

不建议使用:

--daemon选项将继续运行,如果你拥有ssh或cpanel“command”访问权限,可以在命令行上运行一次。


7

Laravel 8 提供了 --max-time 参数给 queue:work 命令,它可以在一定时间后停止作业处理。

php artisan queue:work --max-time=300

你可以设置一个 cron 作业,例如每 5 分钟运行作业处理并将 --max-time 选项设置为 5 分钟 (300 秒)。在这种情况下,cron 将运行作业处理,经过 300 秒后,queue:work 将退出,然后过几秒钟后,cron 将再次运行作业处理,一直循环。

7
最好的方法是在面板任务中设置以下命令(我使用的是 Plesk 控制面板,它使我能够在那里设置任务)。
php artisan queue:work --once

注意:在我的共享主机中,由于服务器配置的原因,我必须设置以下值:

  1. php:/opt/plesk/php/7.2/bin/php -q
  2. artisan:/var/www/vhosts/t4f.ir/httpdocs/artisan
  3. 我的命令:然后我应该输入相应的命令。

因此,结果将是这样的:

/opt/plesk/php/7.2/bin/php -q /var/www/vhosts/t4f.ir/httpdocs/artisan queue:work --once

还有另一种运行时选项,我将其设置为Cron类型,值为: * * * * *,这意味着每分钟都会执行此代码。由于我在命令结尾使用了“--once”,因此一旦执行完命令并完成作业,它将被终止。关于并发执行,我不担心,因为它是由排队系统处理的,这是该系统的责任。


-q 是用来让它变得安静吗? - Michael Sørensen
@MichaelSørensen 老实说,我不知道 :) 我是根据我的最近搜索来使用它的,但很高兴听到你的发现。我会学习的。 - Amin Eshtiaghi

4

2
尝试添加两个cron作业:
  1. 清除缓存:
/usr/local/bin/php /home/<path-to-project>/artisan cache:clear
  1. 运行调度程序
/usr/local/bin/php /home/<path-to-project>/artisan schedule:run

此外,请确保您的app\Console\Kernel.php文件中有类似以下内容的代码:

protected function schedule(Schedule $schedule)
    {
        $schedule->command('queue:work --tries=3')
            ->cron('* * * * *')
            ->withoutOverlapping(5);
    }

如果队列开始工作,请移除第一个任务(即清除缓存的任务)。

我已经完全按照上述操作做了,但什么都没运行。 - Jeche

2

还有一种解决方案(我就是用这种方法解决的同样的问题)。您可以创建如下脚本:

最初的回答:

# getting running processes with name "queue:work"
QUEUE_STATUS=$(ps aux | grep "queue:work")

# check is queue:work started, if no, start it
if $( echo $QUEUE_STATUS | grep --quiet 'artisan queue:work')
then
    exit;
else
    php ~/public_html/artisan queue:work
fi

and run it in CRON. I run every 10 min.


cron检测到有队列工作,但当我在shell上检查时,没有任何关于队列的进程。 - Akbar Noto

0
我找到了一个方法来完成这个hack。
在文件Illuminate\Queue\Worker.php 中,我的当前laravel版本(5.3)位于第151行; 在函数runNextJob($connectionName, $queue, WorkerOptions $options)中添加以下else
if ($job) {
    return $this->process(
        $connectionName, $job, $options
    );
 } else {
    $this->stop();
}

现在创建一个cron job,使用命令php artisan queue:work运行您喜欢的次数,一旦队列耗尽,它将退出(但应频繁存在)。 更新: 使用任务调度程序和 withoutOverlapping()防止重复调用命令,如果它已经在运行,则这是更好的选择,因为之前的选择需要每次 composer install 或 composer update 时做出更改。

0

// 步骤1:运行调度程序

/usr/local/bin/php /home/USERNAME/public_html/PROJECT_FOLDER/artisan schedule:run >> /dev/null 2>&1

// 在 kernel.php 中的第二步

protected function schedule(Schedule $schedule)
    {
        $schedule->command('queue:work', [
        '--max-time' => 300
        ])->withoutOverlapping();

// 步骤 3 测试一下。 ;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接