はじめに
Amazon SQSには、標準キューとFIFOキューがあります。
Laravelに予め用意されているSQSの接続設定(標準キュー用)を使ってFIFOキューにメッセージを送ると、
Error executing "SendMessage" on "https://sqs.ap-northeast-1.amazonaws.com/XXXXXXXXXXXX/hoge.fifo"
The request must contain the parameter MessageGroupId.
となってしまうため、ちょっとした実装で回避します。
前提条件
- Laravel 5.8.24で動作確認しました。
- aws/aws-sdk-phpがインストール済であるものとします。
- Amazon SQSの設定については割愛します。
実装
1.既存のSqsQueueを拡張し、FIFOキューにメッセージを送るサービスを作成します。
namespace App\Services;
class SqsFifoQueue extends \Illuminate\Queue\SqsQueue
{
public function pushRaw($payload, $queue = null, $options = [])
{
$response = $this->sqs->sendMessage([
'QueueUrl' => $this->getQueue($queue),
'MessageBody' => $payload,
'MessageGroupId' => uniqid(),
'MessageDeduplicationId' => uniqid(),
]);
return $response->get('MessageId');
}
}
2.既存のSqsConnectorを拡張し、FIFOキューに接続するサービスを作成します。
namespace App\Services;
use Aws\Sqs\SqsClient;
use Illuminate\Support\Arr;
class SqsFifoConnector extends \Illuminate\Queue\Connectors\SqsConnector
{
public function connect($config)
{
$config = $this->getDefaultConfiguration($config);
if ($config['key'] && $config['secret']) {
$config['credentials'] = Arr::only($config, ['key', 'secret']);
}
return new SqsFifoQueue(new SqsClient($config), $config['prefix'] . '/' . $config['queue']);
}
}
3.FIFOキュー接続用のサービスプロバイダを作成します。
namespace App\Providers;
use App\Services\SqsFifoConnector;
class SqsFifoServiceProvider extends \Illuminate\Support\ServiceProvider
{
public function register()
{
$this->app->afterResolving('queue', function ($manager) {
$manager->addConnector('sqsfifo', function () {
return new SqsFifoConnector;
});
});
}
}
4.作成したサービスプロバイダを登録します。
return [
// ...
'providers' => [
// ...
App\Providers\SqsFifoServiceProvider::class,
],
];
5.FIFOキュー用の接続設定を追加します。
return [
// ...
'connections' => [
// ...
'sqsfifo' => [
'driver' => 'sqsfifo',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX'),
'queue' => env('SQS_QUEUE_FIFO'),
'region' => env('AWS_DEFAULT_REGION'),
],
],
];
6.環境変数の設定例です。(東京リージョンに「hoge.fifo」というFIFOキューを作成した場合)
// ...
SQS_PREFIX=https://sqs.ap-northeast-1.amazonaws.com/XXXXXXXXXXXX
SQS_QUEUE_FIFO=hoge.fifo
7.最後に、使用例です。
HogeJob::dispatch()->onConnection('sqsfifo');
FIFOキューを既定の接続として使う方法や、接続するFIFOキューを指定する方法は、他の接続の場合と同様です。