SQSへのQueue投入をトリガとしてLambda上のLaravelを叩けたら便利そうなので試してみた。
もし Laravel の SQS Queue を Lambda で処理したいのであれば brefphp/laravel-bridge こちらを。
前提
Serverless Framework 導入が前提です。未導入であればこちらなどを参考に導入してください。
Serverless Frameworkの使い方まとめ - Qiita
今回の構成
sqsEvent.php が SQSから呼び出される本体。
SQS -> sqsEvent.php -> QueueController
という流れ。
複数のQueueを扱いやすいよう、QueueController にキューの名称と同じアクション(今回の例は testSqs)を作ると自動的に呼び出されるような形で実装しました。
環境構築
カレントディレクトリへのLaravelのインストールとBrefのインストール。すでに Laravelプロジェクトがある場合は composer require aws/aws-sdk-php
の行から実行してください。
composer create-project --prefer-dist laravel/laravel .
composer require aws/aws-sdk-php
composer require bref/bref
vendor/bin/bref init
serverles.yml と sqsEvent.php
test-app-*-queue という名称で lambda 関数作成する場合。
service: test-app
provider:
name: aws
region: ap-northeast-1
runtime: provided
plugins:
- ./vendor/bref/bref
functions:
queue:
handler: sqsEvent.php
description: ''
layers:
- ${bref:layer.php-73}
events:
- sqs:
# 既存のSQSキューを使う場合
arn: arn:aws:sqs:ap-northeast-1:アカウントID/testSqs
# 新規にSQSキューを作る場合
# arn:
# Fn::GetAtt:
# - PhpQueue
# - Arn
#
#resources:
# Resources:
# PhpQueue:
# Type: AWS::SQS::Queue
# Properties:
# QueueName: testSqs
SQSから呼び出される sqsEvent.php(新規作成)。
<?php
/**
* SQSとの連携動作
*/
declare(strict_types=1);
require __DIR__.'/vendor/autoload.php';
$app = require __DIR__ . '/bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$kernel->bootstrap();
return function (array $event) {
$controller = new App\Http\Controllers\QueueController;
foreach($event['Records'] as $record) {
if (preg_match("/:([^:]+)$/", $record['eventSourceARN'], $matches)) {
$action = $matches[1];
if (!method_exists($controller, $action)) {
echo $record['eventSourceARN'] . " method not exists in QueueController.\n";
echo json_encode($record);
continue;
}
return $controller->$action($record['body']);
} else {
echo $record['eventSourceARN'] . " eventSourceARN error.\n";
echo json_encode($record);
continue;
}
}
};
Queueを処理するコントローラー app/Http/Controllers/QueueController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class QueueController extends Controller
{
//testSqsのQueueを受け取る
public function testSqs($body)
{
// ここに処理を書く
echo $body;
}
}
デプロイ&実行
デプロイ
serverless deploy
Queueを登録して動作を確認しましょう。
aws sqs send-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/アカウントID/testSqs --message-body testtest
CloudWatch Logs で testtest
という出力が確認できるはずです。
ハマりどころ
- S3にアクセスできない
Brefのドキュメントに記述があるが、config/filesystems.php の問題でそのままではアクセスできない。
s3 の設定に token の追加すればアクセスできるようになります。
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
// この token の行を追加
'token' => env('AWS_SESSION_TOKEN'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
],