亚马逊宣布了他们的new FIFO SQS service,我想在Laravel Queue中使用它来解决一些并发问题。
我创建了几个新队列并更改了配置。但是,我收到MissingParameter
错误,说明
The request must contain the parameter MessageGroupId.
所以我修改了文件vendor/laravel/framework/src/Illuminate/Queue/SqsQueue.php
public function pushRaw($payload, $queue = null, array $options = [])
{
$response = $this->sqs->sendMessage(['QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload,
'MessageGroupId' => env('APP_ENV', getenv('APP_ENV'))]);
return $response->get('MessageId');
}
public function later($delay, $job, $data = '', $queue = null)
{
$payload = $this->createPayload($job, $data);
$delay = $this->getSeconds($delay);
return $this->sqs->sendMessage([
'QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload, 'DelaySeconds' => $delay,
'MessageGroupId' => env('APP_ENV', getenv('APP_ENV'))
])->get('MessageId');
}
我使用APP_ENV
作为群组ID(它是一个单一的消息队列,所以实际上它并不重要。我只想要一切都是FIFO)。
但我仍然收到相同的错误消息。我该怎么办呢?任何帮助将不胜感激。
(顺便说一句,SDK定义在哪里sendMessage
?我可以找到它的存根,但我没有找到详细的实现)
答案 0 :(得分:16)
我想指出那些可能偶然遇到同一问题的人,尽管编辑SqsQueue.php
有效,但很容易被composer install
或composer update
重置。另一种方法是为SQS FIFO实现一个新的Illuminate\Queue\Connectors\ConnectorInterface
,然后将其添加到Laravel的队列管理器中。
我的方法如下:
SqsFifoQueue
但支持SQS FIFO的新Illuminate\Queue\SqsQueue
类。SqsFifoConnector
类,扩展Illuminate\Queue\Connectors\SqsConnector
,使用SqsFifoQueue
建立连接。SqsFifoServiceProvider
,将SqsFifoConnector
注册到Laravel的队列管理器。SqsFifoServiceProvider
添加到您的config/app.php
。config/queue.php
以使用新的SQS FIFO队列驱动程序。示例:强>
创建一个扩展SqsFifoQueue
但支持SQS FIFO的新Illuminate\Queue\SqsQueue
类。
<?php
class SqsFifoQueue extends \Illuminate\Queue\SqsQueue
{
public function pushRaw($payload, $queue = null, array $options = [])
{
$response = $this->sqs->sendMessage([
'QueueUrl' => $this->getQueue($queue),
'MessageBody' => $payload,
'MessageGroupId' => uniqid(),
'MessageDeduplicationId' => uniqid(),
]);
return $response->get('MessageId');
}
}
创建一个新的SqsFifoConnector
类,扩展Illuminate\Queue\Connectors\SqsConnector
,使用SqsFifoQueue
建立连接。
<?php
use Aws\Sqs\SqsClient;
use Illuminate\Support\Arr;
class SqsFifoConnector extends \Illuminate\Queue\Connectors\SqsConnector
{
public function connect(array $config)
{
$config = $this->getDefaultConfiguration($config);
if ($config['key'] && $config['secret']) {
$config['credentials'] = Arr::only($config, ['key', 'secret']);
}
return new SqsFifoQueue(
new SqsClient($config), $config['queue'], Arr::get($config, 'prefix', '')
);
}
}
创建一个新的SqsFifoServiceProvider
,将SqsFifoConnector
注册到Laravel的队列管理器。
<?php
class SqsFifoServiceProvider extends \Illuminate\Support\ServiceProvider
{
public function register()
{
$this->app->afterResolving('queue', function ($manager) {
$manager->addConnector('sqsfifo', function () {
return new SqsFifoConnector;
});
});
}
}
将SqsFifoServiceProvider
添加到config/app.php
。
<?php
return [
'providers' => [
...
SqsFifoServiceProvider::class,
],
];
更新config/queue.php
以使用新的SQS FIFO队列驱动程序。
<?php
return [
'default' => 'sqsfifo',
'connections' => [
'sqsfifo' => [
'driver' => 'sqsfifo',
'key' => 'my_key'
'secret' => 'my_secret',
'queue' => 'my_queue_url',
'region' => 'my_sqs_region',
],
],
];
然后你的队列现在应该支持SQS FIFO队列。
无耻插件:在执行上述步骤时,我创建了一个laravel-sqs-fifo作曲家包,以便在https://github.com/maqe/laravel-sqs-fifo处理此问题。
答案 1 :(得分:2)
FIFO消息的工作方式与标准AWS SQS队列不同。
您需要一个单独的驱动程序来处理FIFO队列。
我不得不面对同样的情况,下面的包裹是救生员。
https://packagist.org/packages/shiftonelabs/laravel-sqs-fifo-queue
在queue.php
'sqs-fifo' => [
'driver' => 'sqs-fifo',
'key' => env('SQS_KEY'),
'secret' => env('SQS_SECRET'),
'prefix' => env('SQS_PREFIX'),
'queue' => env('SQS_QUEUE'),
'region' => env('SQS_REGION'),
'group' => 'default',
'deduplicator' => 'unique',
],
然后
dispatch(new TestJob([]))->onQueue('My_Mail_Queue.fifo');
注意:
您需要在.env
SQS_QUEUE=My_Default_queue.fifo
此外,您需要在侦听器中指定要在应用程序中使用的所有队列名称。 (如果您为整个应用程序使用相同的队列名称,则无需在侦听器中指定队列名称)
php artisan queue:listen --queue=My_Default_queue.fifo,My_Mail_Queue.fifo,My_Message_Queue.fifo
答案 2 :(得分:0)
除open class UnitFlowRate : Dimension {
open override static func baseUnit() -> UnitFlowRate { return self.metricTonsPerHour }
static let shortTonsPerHour = UnitFlowRate(symbol: NSLocalizedString("stph", comment: "short tons per hour"), converter: UnitConverterLinear(coefficient: 0.5))
static let metricTonsPerHour = UnitFlowRate(symbol: NSLocalizedString("mtph", comment: "metric tons per hour"), converter: UnitConverterLinear(coefficient: 1))
}
外,它还需要MessageGroupId
或启用基于内容的重复数据删除。