如何在 redis 上的 laravel 队列中获取所有待处理的作业?

Posted

技术标签:

【中文标题】如何在 redis 上的 laravel 队列中获取所有待处理的作业?【英文标题】:How to get all pending jobs in laravel queue on redis? 【发布时间】:2016-05-26 13:33:01 【问题描述】:

queue:listen 未在服务器上运行,因此一些作业被推送(使用 Redis 驱动程序)但从未运行。

我如何计算(或获得所有)这些工作?我没有找到任何工匠命令来获取此信息。

【问题讨论】:

【参考方案1】:

如果有人还在寻找答案,我就是这样做的:

$connection = null;
$default = 'default';

// For the delayed jobs
var_dump(
    \Queue::getRedis()
        ->connection($connection)
        ->zrange('queues:'.$default.':delayed', 0, -1)
);
    
// For the reserved jobs
var_dump(
    \Queue::getRedis()
        ->connection($connection)
        ->zrange('queues:'.$default.':reserved', 0, -1)
);

$connection是Redis的连接名称,默认为null$default是队列的名称,默认为default

【讨论】:

有没有办法只获取保留作业的数量而无需进一步处理/评估结果数组? 对于 Laravel 5.8,我必须使用 lrange 命令而不是 zrange -1 不是为我做的...我用 99999 并且工作正常。【参考方案2】:

从 Laravel 5.3 开始,您可以简单地使用 Queue::size()(参见 PR)。

【讨论】:

对特定队列使用Queue::size('queue-name');【参考方案3】:

你也可以这样做直接使用 Redis Facade:

use Redis;

\Redis::lrange('queues:$queueName', 0, -1);

在 Laravel 5.6 中测试,但应该适用于所有 5.X。

【讨论】:

【参考方案4】:

如果您在队列中使用redis 驱动程序,您可以按名称计数所有剩余的作业:

use Redis;

// List all keys with status (awaiting, reserved, delayed)
Redis::keys('*');

// Count by name
$queueName = 'default';
echo Redis::llen('queues:' . $queueName);

// To count by status:
echo Redis::zcount('queues:' . $queueName . ':delayed', '-inf', '+inf');
echo Redis::zcount('queues:' . $queueName . ':reserved', '-inf', '+inf');

要立即查看结果,您可以使用php artisan tinker 并点击Redis::llen('queues:default');

【讨论】:

为什么我们需要 // 列出所有具有状态(等待、保留、延迟)的键 Redis::keys('*');根据使用情况,在生产中这可能会很繁重? @ShivdhwajPandey 因为我不确定它的性能 (Redis::keys('*');),所以你是对的,谢谢 (***.com/a/32604218/4728084)。我只是在此处列出它们以在 dev 或 stg 环境中进行调试。对于这种情况,您在 Prod env 中有什么推荐的命令吗?请与我们分享! :弓: 【参考方案5】:

您可以安装 Horizo​​n。 Laravel Horizo​​n 提供了一个仪表板来监控你的队列,并允许你对你的队列进行更多的配置。

composer require laravel/horizon

php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"

您必须设置.env 配置文件和config/horizon.php 文件。

用 Laravel 5.6 测试

【讨论】:

【参考方案6】:

我的 laravel 5.7 项目中有两个队列,一个默认队列和一个 low_prio 队列。

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class JobsOnQueue extends Command


    // su -c "php artisan jobs:on:queue" -s /bin/sh www-data

    protected $signature = 'jobs:on:queue';

    protected $description = 'Print jobs in redis';

    protected $lines = [];

    public function handle()
    

        $connection = null;

        $queuename       = 'default';
        $default_delayed = \Queue::getRedis()
            ->connection($connection)
            ->zrange('queues:' . $queuename . ':delayed', -9999, 9999);

        $default_reserved = \Queue::getRedis()
            ->connection($connection)
            ->zrange('queues:' . $queuename . ':reserved', -9999, 9999);

        $queuename        = 'low_prio';
        $low_prio_delayed = \Queue::getRedis()
            ->connection($connection)
            ->zrange('queues:' . $queuename . ':delayed', -9999, 9999);

        $low_prio_reserved = \Queue::getRedis()
            ->connection($connection)
            ->zrange('queues:' . $queuename . ':reserved', -9999, 9999);

        $this->getQueueData('default delayed', $default_delayed);
        $this->getQueueData('default reserved', $default_reserved);
        $this->getQueueData('low prio delayed', $low_prio_delayed);
        $this->getQueueData('low prio reserved', $low_prio_reserved);

        $this->info(join("\n", $this->lines));

    

    private function getQueueData($title, $arr)
    
        $this->lines[] = "*** $title ***";
        if (count($arr) == 0) 
            $this->lines[] = "Nothing on queue";
            $this->lines[] = "";
            return;
        

        foreach ($arr as $json) 
            $queue = json_decode($json);
            $data  = $queue->data;

            if (isset($data) && isset($data->command)) 
                $this->getCommands($data->command);
            
        
        $this->lines[] = "";

    

    private function getCommands($serialized)
    

        $readable = str_replace(
            'O:43:"Illuminate\Foundation\Console\QueuedCommand',
            'O:33:"App\Support\ReadableQueuedCommand',
            $serialized);

        $readable = unserialize($readable);
        $command  = $readable->getData();

        $attribs = [];
        $options = $command[1];
        foreach ($options as $key => $value) 
            $attribs[] = $key . '=' . $value;
        

        $this->lines[] = $command[0] . ' ' . join(" - ", $attribs);
    


ReadableQueuedCommand 看起来像这样

<?php

namespace App\Support;

use Illuminate\Foundation\Console\QueuedCommand;

class ReadableQueuedCommand extends QueuedCommand

    public function getData()
    
        return $this->data;
    

artisan 命令然后列出队列中的所有内容

> php artisan jobs:on:queue

*** default delayed ***
Nothing on queue

*** default reserved ***
Nothing on queue

*** low prio delayed ***
Nothing on queue

*** low prio reserved ***
oppty:time:profile --by-dataset=2
oppty:on:reset:pages --by-dataset=2

【讨论】:

【参考方案7】:

如果有人仍在寻找旧版本 Laravel 的方法:

$connection = 'queue';
$queueName = 'default';

$totalQueuedLeads = Redis::connection($connection)
    ->zcount('queues:'.$queueName.':delayed' , '-inf', '+inf');

【讨论】:

以上是关于如何在 redis 上的 laravel 队列中获取所有待处理的作业?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 队列与 beanstalkd 和 redis 重复

无法获得工匠队列:在 Elastic Beanstalk (Laravel/Redis) 上使用主管处理作业

Laravel 6 在生产环境中如何管理队列?

[原创]Laravel 基于redis队列的解析

如何让 Laravel 与 AWS 上的 Redis 集群一起工作

laravel中redis队列的使用