LoginSignup
1
2

More than 3 years have passed since last update.

SQSからLambda上のLaravelを動かす

Last updated at Posted at 2020-07-17

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 関数作成する場合。

serverless.yml
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(新規作成)。

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

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 という出力が確認できるはずです。

ハマりどころ

  1. 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'),
        ],
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2