主管无法处理多个网站的Laravel队列

主管无法处理多个网站的Laravel队列,laravel,supervisord,Laravel,Supervisord,将运行Laravel队列的单个网站添加到主管时,延迟的作业将按其应有的方式进行处理 当我向主管添加另一个网站时,任何网站/队列都不会处理延迟的作业 我已尝试重新阅读、重新加载和重新启动服务。supervisord.log显示所有正在运行的进程,但未触发作业 如果我停止除1个工人以外的所有工人,则队列工作 拉威尔5.7 第3.3.1条 redis cli 3.2.6 Debian/Nginx sudo nano /etc/supervisor/conf.d/website-a-worker.con

将运行Laravel队列的单个网站添加到主管时,延迟的作业将按其应有的方式进行处理

当我向主管添加另一个网站时,任何网站/队列都不会处理延迟的作业

我已尝试重新阅读、重新加载和重新启动服务。supervisord.log显示所有正在运行的进程,但未触发作业

如果我停止除1个工人以外的所有工人,则队列工作

拉威尔5.7

第3.3.1条

redis cli 3.2.6

Debian/Nginx

sudo nano /etc/supervisor/conf.d/website-a-worker.conf
工作永远不会被触发。 然而,若我停止网站b的主管,网站a将处理作业

> sudo supervisorctl stop website-b-worker:*
website-b-worker:website-b-worker_02: stopped
website-b-worker:website-b-worker_03: stopped
website-b-worker:website-b-worker_00: stopped
website-b-worker:website-b-worker_01: stopped
website-b-worker:website-b-worker_06: stopped
website-b-worker:website-b-worker_07: stopped
website-b-worker:website-b-worker_04: stopped
website-b-worker:website-b-worker_05: stopped

> php artisan tinker

>>> App\Jobs\SomeJob::dispatch()->delay(1);
# Job gets triggered!


如何运行多个Worker(每个网站至少一个)?

我使用过Laravel和Redis的Supervisor,但一次只能运行一个网站。但是,我做了一些研究,发现可以在Laravel中指定队列进程的名称

Laravel
作业
有一个setter方法
onQueue()
,用于指定队列的名称。laravel文档示例:

Job::dispatch()->onQueue('emails');
但是在你的代码
SomeJob
中,你可以直接用
$this->onQueue('queue_name')
调用它;您的代码可以是:

<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

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

    public function handle()
    {
        // on website a
        $this->onQueue('websiteAQueue');
        \Log::info('This only gets triggered if 1 supervisor worker is running.');
    }
}
这样,当Laravel发送作业时,它会将作业发送到指定的队列,而不是它找到的默认队列

编辑----------------------

或者更好,您可以为每个网站配置使用不同的队列名称:

// Website A : config/queue.php
...
'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => 'websiteAQueue',
            'retry_after' => 600,
            'block_for' => null,
        ],
...

通过这种方式,所有队列都会自动发送到
websiteAQueue
,因此您不必在每个作业上使用
$This->onQueue()

我从未在多个网站上尝试过supervisord。但是关于你有很多网站,
numprocs
值可以吗?请看我在答案中的编辑,这比在每个作业上放置
$this->onQueue()
更好,并在队列配置中设置队列名称auto:
'queue'=>'websiteAQueue',
。是的,最后我使用了第二个选项——编辑config/queue.php,更改每个站点的队列名称,并在.conf中指定队列名称。
// config/queue.php
...
'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => 'default',
            'retry_after' => 600,
            'block_for' => null,
        ],
...
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

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

    public function handle()
    {
       \Log::info('This only gets triggered if 1 supervisor worker is running.');
    }
}
> sudo service supervisor restart
> cd /var/www/website.a
> php artisan tinker

>>> App\Jobs\SomeJob::dispatch()->delay(1);
# Job does not get triggered
>>> exit
> sudo supervisorctl stop website-b-worker:*
website-b-worker:website-b-worker_02: stopped
website-b-worker:website-b-worker_03: stopped
website-b-worker:website-b-worker_00: stopped
website-b-worker:website-b-worker_01: stopped
website-b-worker:website-b-worker_06: stopped
website-b-worker:website-b-worker_07: stopped
website-b-worker:website-b-worker_04: stopped
website-b-worker:website-b-worker_05: stopped

> php artisan tinker

>>> App\Jobs\SomeJob::dispatch()->delay(1);
# Job gets triggered!

Job::dispatch()->onQueue('emails');
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

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

    public function handle()
    {
        // on website a
        $this->onQueue('websiteAQueue');
        \Log::info('This only gets triggered if 1 supervisor worker is running.');
    }
}
[program:website-a-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/website.a/artisan queue:work redis --queue=WebsiteAQueue --sleep=3 --tries=3
autostart=true
autorestart=true
#user=laravel
numprocs=8
autostart=true
autorestart=true
stdout_logfile=/var/www/website.a/storage/logs/worker.log
stderr_logfile=/var/www/website.a/storage/logs/worker.err.log
// Website A : config/queue.php
...
'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => 'websiteAQueue',
            'retry_after' => 600,
            'block_for' => null,
        ],
...