LaravelにあるQueue機能
AWS SQSに入ったメッセージを、Laravelフレームワークで処理したいことがあった。
LaravelにはもともとQueueの機能があり、それを使うことで簡易にできると思っていたが、これはLaravelからエンキューしLaravelからデキューする前提で作られているようだった。(?)
実際にJOBを投入するときは、処理するロジックのクラスも含めてエンキューする。
エンキューする際は決まった形にオブジェクトを作成し、デキューする際もそれ前提で処理をするようだった。
以下はエンキューする前に呼び出される関数。
ペイロードのオブジェクトをLaravelの仕様で作っている。
/**
* Create a payload for an object-based queue handler.
*
* @param mixed $job
* @return array
*/
protected function createObjectPayload($job)
{
return [
'displayName' => $this->getDisplayName($job),
'job' => 'Illuminate\Queue\CallQueuedHandler@call',
'maxTries' => $job->tries ?? null,
'timeout' => $job->timeout ?? null,
'timeoutAt' => $this->getJobExpiration($job),
'data' => [
'commandName' => get_class($job),
'command' => serialize(clone $job),
],
];
}
今回やりたいこと
SQSにはLaravelではない別のクライアントからメッセージを入れる。
この入れられたメッセージをLaravelで処理したい。
もちろんLambdaなどで処理したほうがいいケースのほうが多そうだが、今回はプロジェクトの仕様でLaravelで行いたい。
config/queue.php
今後Laravelの既存Queue機能を使うかもしれないので、configの場所は同じにする。
もともと以下の記述があるので、実際には.envへの追記になる。
'sqs' => [
'driver' => 'sqs',
'key' => env('SQS_KEY', 'your-public-key'),
'secret' => env('SQS_SECRET', 'your-secret-key'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('SQS_REGION', 'us-east-1'),
],
AWS SDK
composerでrequire
$ composer require aws/aws-sdk-php
メッセージのデキュー
AWSクライアントを直接使うのではなく、config処理をそのまま活かすために、Laravelのクラスを使ってみた。
(Laravelのクラスの中で、AWSのSDKを使っている)
use Illuminate\Queue\Connectors\SqsConnector;
/** 省略 **/
public function handle()
{
$config = config('queue.connections.sqs');
$client = (new SqsConnector())->connect($config);
$sqs = $client->getSqs();
$queue_url = $client->getQueue(null);
$result = $sqs->receiveMessage([...]);
...
}