首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调度到队列总是选择默认连接。

调度到队列总是选择默认连接。
EN

Stack Overflow用户
提问于 2019-11-18 12:19:42
回答 1查看 787关注 0票数 1

我有一个应用程序运行许多不同类型的作业,运行几秒钟到一个小时。这要求我有两个独立的队列连接,因为retry_after被绑定到一个连接,而不是一个队列(尽管它们都使用Redis,这很烦人,但现在不是问题)。一个连接的retry_after为600秒,另一个为3600秒(或一小时)。我的工作实现了ShouldQueue并使用了特性Queueable, SerializesModels, Dispatchable, InteractsWithQueue

现在是问题所在。我创建了一个睡眠900秒的TestJob,以确保我们通过了retry_after限制。当我试图使用:dispatch(new Somejob)->onConnection('redis-long-run')或以前在作业的构造函数中(过去总是工作)分配特定连接上的作业时:

代码语言:javascript
复制
public function __construct() {
    $this->onConnection('redis-long-run');
}

作业由队列工作人员拾取,运行600秒后,员工重新启动作业,注意到它已经运行了一次,并失败了。300秒后,作业处理成功。如果我的工作人员允许多次尝试,重复作业将并行运行300秒。

在我的测试工作中,我还打印出了$this->connection,它确实显示了正在使用的正确连接,所以我猜广播公司只是完全忽略了它。

我在Docker环境中使用Laravel5.8.35和PHP7.3。主管处理我的工人。

编辑:我已经确认在升级到Laravelv6.5.1之后,这种行为仍然存在。

复制步骤:

  1. 将您的队列驱动程序设置为Redis,
  2. 在queue.php中创建两个不同的Redis连接,一个名为redis,其retry_after值为600,另一个名为redis-long-run,retry_after为3600。在我的例子中,它们也有不同的队列,尽管我不确定这个测试是否需要这样做。

代码语言:javascript
复制
    'connections' => [
        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => env('REDIS_QUEUE', 'default'),
            'retry_after' => 600,
            'block_for' => null,
        ],

        'redis-long-run' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => 'long_run',
            'retry_after' => 3600,
            'block_for' => null,
        ]
    ]

  1. 创建一个小命令来分派我们的测试作业三次

代码语言:javascript
复制
<?php

namespace App\Console\Commands;

use App\Jobs\TestFifteen;
use Illuminate\Console\Command;

class TestCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'test:fifteen';

    /**
     * Create a new command instance.
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        for ($i = 1; $i <= 3; $i++) {
            dispatch(new TestFifteen($i))->onConnection('redis-long-run');
        }
    }
}

  1. 创建测试作业

代码语言:javascript
复制
<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use function sleep;
use function var_dump;

class TestFifteen implements ShouldQueue
{
    use Queueable, SerializesModels, Dispatchable, InteractsWithQueue;

    private $testNumber;

    public function __construct($testNumber)
    {
        $this->onConnection('redis-long-run');
        $this->testNumber = $testNumber;
    }

    public function handle()
    {
        var_dump("Started test job {$this->testNumber} on connection {$this->connection}");
        sleep(900);
        var_dump("Finished test job {$this->testNumber} on connection {$this->connection}");
    }
}

  1. 运行队列工作器。我对这些工作人员使用以下配置的主管。

代码语言:javascript
复制
[program:laravel-queue-default]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/artisan queue:work redis --queue=default --tries=3 --timeout=600
numprocs=8
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:laravel-queue-long-run]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/artisan queue:work redis --queue=long_run --tries=1 --timeout=3540
numprocs=8
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

执行手工命令php artisan test:fifteen

那么,我是做错了什么,还是应用的联系真的不受尊重?

此外,不能够根据每个作业或队列来决定retry_after应该是什么,从而能够使用REDIS作为实际的队列驱动程序,背后的设计理念是什么?为什么我不能选择Redis作为队列处理程序,并决定队列-60秒后重试1次,120秒后重试2次队列?当他们使用完全相同的Redis实例和所有东西时,我觉得必须为此建立两个连接是非常不自然的。

不管怎么说,我希望一些人能在这个问题上有所启发。提前谢谢你。

EN

回答 1

Stack Overflow用户

发布于 2019-11-19 08:33:26

据我所知,您的连接始终是redis,因此您应该在分派时指定队列:

代码语言:javascript
复制
dispatch(new TestFifteen($i))->onQueue('long_run');

connection 是一个不同的驱动程序,如redis、sync、AWS等,而queue是与该连接不同的配置或多个作业堆栈。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58914428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档