はじめに
LaravelのキューはLaravelから投入してLaravelで処理する前提になっているので、そのままだと外部の仕組みから投入したメッセージを処理することはできません。
この投稿にあるように、{"job":"Acme\\Jobs\\PushFilesJob","data":{"file_id":"1"}}
のようなJSON形式で送信されていないとキューの中身とジョブの紐づけができないからです。
このフォーマットで送ってくれるならいいですが、外部の仕組みだとそうもいかないことがほとんどだと思います。
そこでなんか方法ないかと調べたところよさげなプラグインを発見。
ただ、README.mdがなかなか不親切だったため導入に難儀したので手順を残します。
Laravel6系で試しています。
インストール
Composerでインストール。
>composer require dusterio/laravel-plain-sqs
>composer require aws/aws-sdk-php-laravel
'providers' => [
// ~中略~
/*
* Package Service Providers...
*/
Dusterio\PlainSqs\Integrations\LaravelServiceProvider::class,
Aws\Laravel\AwsServiceProvider::class,
設定
ライブラリの設定ファイルをpublishします。
>php artisan vendor:publish --provider Dusterio\PlainSqs\Integrations\LaravelServiceProvider
Copied File [\vendor\dusterio\laravel-plain-sqs\src\config\sqs-plain.php] To [\config\sqs-plain.php]
Publishing complete.
ライブラリの設定ファイルに呼び出したいジョブのクラスを指定。
handlers
を使うとキュー名に対応したジョブを呼び出せるそう。
<?php
/**
* List of plain SQS queues and their corresponding handling classes
*/
return [
'handlers' => [
'foo-queue' => App\Jobs\BarJob::class,
],
'default-handler' => App\Jobs\SampleJob::class
];
キューの設定ファイルにlaravel-plain-sqs
用の情報を追加。
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
'sqs-plain' => [
'driver' => 'sqs-plain',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
.env
にAWSリソースの情報追加。
あらかじめSQSキューとアクセスできるIAMが用意されてる前提です。
QUEUE_CONNECTION=sqs-plain
AWS_ACCESS_KEY_ID=*****************
AWS_SECRET_ACCESS_KEY=*******************************************
AWS_DEFAULT_REGION=ap-northeast-1
SQS_PREFIX=https://sqs.ap-northeast-1.amazonaws.com/999999999999
SQS_QUEUE=MyQueue
ジョブの作成
キューのメッセージを受信して処理するジョブを作成します。
Readme.mdそのままだと動かせなかったのでこちらのイシューを参考に(マージしてほしい…)。
>php artisan make:job SampleJob
<?php
namespace App\Jobs;
use Illuminate\Queue\Jobs\Job;
use Illuminate\Support\Facades\Log;
class SampleJob extends Job
{
/**
* Execute the job.
* @param Job $job
* @param array $data
*/
public function handle(Job $job, array $data)
{
// This is incoming JSON payload, already decoded to an array
Log::info($data);
// Raw JSON payload from SQS, if necessary
Log::info($job->getRawBody());
}
public function getRawBody() {}
public function getJobId() {}
}
動作確認
ワーカーを起動させて、キューにデータを投入します。
>php artisan queue:work
[2021-11-14 15:13:05][f8984da8-6cb7-4d1c-a328-f4c1b850679c] Processing: App\Jobs\SampleJob@handle
[2021-11-14 15:13:05][f8984da8-6cb7-4d1c-a328-f4c1b850679c] Processed: App\Jobs\SampleJob@handle
{"foo":1,"bar":true}
適当なJSONを送ってみる。
[2021-11-14 15:13:05] local.INFO: array (
'foo' => 1,
'bar' => true,
)
[2021-11-14 15:13:05] local.INFO: {"job":"App\\Jobs\\SampleJob@handle","data":{"foo":1,"bar":true},"uuid":"f8984da8-6cb7-4d1c-a328-f4c1b850679c"}