如何从环境变量设置侦听器队列名称?
How to set listener queue name from environment variable?
我刚刚注意到我的一些听众没有使用我期望他们使用的队列。几周前,我们的团队从 Laravel 5.2 升级到了 5.5,我想这就是问题开始出现的时候。一直以来系统负载不大,偶然发现的
无论如何。我曾经通过队列方法在侦听器上设置队列名称,如下所示:
public function queue(QueueManager $handler, $method, $arguments): void
{
$handler->connection()->push($method, $arguments, Queue::getNotificationQueue());
}
这种方法不再有效,因此默认队列最终处理作业而不是预期的通知队列。
所以我查看了文档 https://laravel.com/docs/5.5/events#queued-event-listeners,其中指出名称应该设置在侦听器的队列 属性 上。我的问题是我在环境变量中有队列名称,所以我不能直接将它设置为 属性,如文档中所示,并且在构造函数中设置它不起作用,如下所示:
protected $queue;
public function __construct()
{
$this->queue = Queue::getNotificationQueue();
}
这里有人知道我该如何解决这个问题吗?
特别是对于 SQS 队列,$queue
属性 表现得有点奇怪,因为它似乎没有引用 queue.php
中定义的队列,但它需要一个完整的队列 url,所以即使文档中的示例也似乎不正确。
但是对于排队事件侦听器上的动态队列名称,例如根据环境而变化,自定义 SqsConnector
和 SqsQueue
将是解决问题的一种方法。
这是一个实现示例。
ACMEEventListener.php
class ACMEEventListener implements ShouldQueue
{
public function handle(Event $event): void
{
// I'm going to a custom queue
}
public static function getQueue(): string
{
return 'https://sqs.eu-central-1.amazonaws.com/<account id>/<queue name>';
}
}
CustomSqsConnector.php
use Illuminate\Queue\Connectors\SqsConnector;
use Aws\Sqs\SqsClient;
class CustomSqsConnector extends SqsConnector
{
public function connect(array $config)
{
$sqs = new SqsClient($config);
return new CustomSqsQueue($sqs, $config['queue']);
}
}
CustomSqsQueue.php
class CustomSqsQueue extends \Illuminate\Queue\SqsQueue
{
public function push($job, $data = '', $queue = null)
{
if ($job instanceof CallQueuedListener && method_exists($job->class, 'getQueue')) {
$queue = $job->class::getQueue();
}
return $this->pushRaw($this->createPayload($job, $data), $queue);
}
}
CustomSqsQueueServiceProvider.php
class CustomSqsQueueServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->booted(function () {
$this->app['queue']->extend('custom_sqs', function () {
return new CustomSqsConnector;
});
});
}
}
然后在您的 queue.php
中,您的默认 SQS 连接驱动程序从 sqs
到 custom_sqs
我刚刚注意到我的一些听众没有使用我期望他们使用的队列。几周前,我们的团队从 Laravel 5.2 升级到了 5.5,我想这就是问题开始出现的时候。一直以来系统负载不大,偶然发现的
无论如何。我曾经通过队列方法在侦听器上设置队列名称,如下所示:
public function queue(QueueManager $handler, $method, $arguments): void
{
$handler->connection()->push($method, $arguments, Queue::getNotificationQueue());
}
这种方法不再有效,因此默认队列最终处理作业而不是预期的通知队列。
所以我查看了文档 https://laravel.com/docs/5.5/events#queued-event-listeners,其中指出名称应该设置在侦听器的队列 属性 上。我的问题是我在环境变量中有队列名称,所以我不能直接将它设置为 属性,如文档中所示,并且在构造函数中设置它不起作用,如下所示:
protected $queue;
public function __construct()
{
$this->queue = Queue::getNotificationQueue();
}
这里有人知道我该如何解决这个问题吗?
特别是对于 SQS 队列,$queue
属性 表现得有点奇怪,因为它似乎没有引用 queue.php
中定义的队列,但它需要一个完整的队列 url,所以即使文档中的示例也似乎不正确。
但是对于排队事件侦听器上的动态队列名称,例如根据环境而变化,自定义 SqsConnector
和 SqsQueue
将是解决问题的一种方法。
这是一个实现示例。
ACMEEventListener.php
class ACMEEventListener implements ShouldQueue
{
public function handle(Event $event): void
{
// I'm going to a custom queue
}
public static function getQueue(): string
{
return 'https://sqs.eu-central-1.amazonaws.com/<account id>/<queue name>';
}
}
CustomSqsConnector.php
use Illuminate\Queue\Connectors\SqsConnector;
use Aws\Sqs\SqsClient;
class CustomSqsConnector extends SqsConnector
{
public function connect(array $config)
{
$sqs = new SqsClient($config);
return new CustomSqsQueue($sqs, $config['queue']);
}
}
CustomSqsQueue.php
class CustomSqsQueue extends \Illuminate\Queue\SqsQueue
{
public function push($job, $data = '', $queue = null)
{
if ($job instanceof CallQueuedListener && method_exists($job->class, 'getQueue')) {
$queue = $job->class::getQueue();
}
return $this->pushRaw($this->createPayload($job, $data), $queue);
}
}
CustomSqsQueueServiceProvider.php
class CustomSqsQueueServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->booted(function () {
$this->app['queue']->extend('custom_sqs', function () {
return new CustomSqsConnector;
});
});
}
}
然后在您的 queue.php
中,您的默认 SQS 连接驱动程序从 sqs
到 custom_sqs