Laravel 与 Supervisor 一起排队无法使用多个网站
Laravel Queue with Supervisor not working with Multiple Websites
将单个网站 运行 宁 Laravel 队列添加到 Supervisor 时,延迟的作业将按应有的方式处理。
当我将另一个网站添加到 Supervisor 时,任何 websites/queues.
的延迟作业都不会处理
我试过重新读取、重新加载和重新启动服务。 supervisord.log 显示所有进程 运行ning,但未触发作业。
如果我停止除 1 个工作人员以外的所有工作人员,队列就会工作。
Laravel 5.7
监督者 3.3.1
redis-cli 3.2.6
Debian/Nginx
sudo nano /etc/supervisor/conf.d/website-a-worker.conf
[program:website-a-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/website.a/artisan queue:work redis --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
sudo nano /etc/supervisor/conf.d/website-b-worker.conf
[program:website-b-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/website.b/artisan queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
#user=laravel
numprocs=8
autostart=true
autorestart=true
stdout_logfile=/var/www/website.b/storage/logs/worker.log
stderr_logfile=/var/www/website.b/storage/logs/worker.err.log
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start website-a-worker:*
sudo supervisorctl start website-b-worker:*
// 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
作业永远不会被触发。
但是,如果我停止 website.b 的主管,website.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!
如何 运行 多个工作人员(每个网站至少 1 个)?
我已经将 Supervisor 与 Laravel 和 Redis 一起使用,但一次只能用于 1 个网站。但是我做了一些研究,发现您可以在 Laravel https://laravel.com/docs/5.8/queues#connections-vs-queues .
中指定队列进程的名称
A Laravel Job
有一个 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.');
}
}
并且在网站A的Supervisor进程中,指定queue参数为websiteAQueue
:
[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
这样当 Laravel 发送作业时,它会将其发送到指定的队列而不是它找到的默认队列。
编辑------------------------
或者更好的是,您可以为每个网站配置使用不同的队列名称:
// Website A : config/queue.php
...
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'websiteAQueue',
'retry_after' => 600,
'block_for' => null,
],
...
这样所有队列都会自动发送到 websiteAQueue
,因此您不必在每个作业上使用 $this->onQueue()
。
将单个网站 运行 宁 Laravel 队列添加到 Supervisor 时,延迟的作业将按应有的方式处理。
当我将另一个网站添加到 Supervisor 时,任何 websites/queues.
的延迟作业都不会处理我试过重新读取、重新加载和重新启动服务。 supervisord.log 显示所有进程 运行ning,但未触发作业。
如果我停止除 1 个工作人员以外的所有工作人员,队列就会工作。
Laravel 5.7
监督者 3.3.1
redis-cli 3.2.6
Debian/Nginx
sudo nano /etc/supervisor/conf.d/website-a-worker.conf
[program:website-a-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/website.a/artisan queue:work redis --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
sudo nano /etc/supervisor/conf.d/website-b-worker.conf
[program:website-b-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/website.b/artisan queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
#user=laravel
numprocs=8
autostart=true
autorestart=true
stdout_logfile=/var/www/website.b/storage/logs/worker.log
stderr_logfile=/var/www/website.b/storage/logs/worker.err.log
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start website-a-worker:*
sudo supervisorctl start website-b-worker:*
// 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
作业永远不会被触发。 但是,如果我停止 website.b 的主管,website.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!
如何 运行 多个工作人员(每个网站至少 1 个)?
我已经将 Supervisor 与 Laravel 和 Redis 一起使用,但一次只能用于 1 个网站。但是我做了一些研究,发现您可以在 Laravel https://laravel.com/docs/5.8/queues#connections-vs-queues .
中指定队列进程的名称A Laravel Job
有一个 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.');
}
}
并且在网站A的Supervisor进程中,指定queue参数为websiteAQueue
:
[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
这样当 Laravel 发送作业时,它会将其发送到指定的队列而不是它找到的默认队列。
编辑------------------------
或者更好的是,您可以为每个网站配置使用不同的队列名称:
// Website A : config/queue.php
...
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'websiteAQueue',
'retry_after' => 600,
'block_for' => null,
],
...
这样所有队列都会自动发送到 websiteAQueue
,因此您不必在每个作业上使用 $this->onQueue()
。