はじめに
仕事でsqs+lambdaを使って非同期処理を実装したので、復習がてら記事にしています。
本当は、 DLQを設定してDLQに入るとCloudWatchからslackに通知を飛ばすという風にしたかったのですが、上手くいかなかったので、追記するか別記事にしようと思います。
Serverless Frameworkからプロジェクトの作成
まず、Serverless Frameworkをインストールします。
@ueMac [~/dev]
[ueyuki]-> npm install -g serverless
@ueMac [~/dev]
[ueyuki]-> serverless -v
Framework Core: 1.74.1
Plugin: 3.6.15
SDK: 2.3.1
Components: 2.31.11
Serverless Frameworkでは、テンプレートを使用してプロジェクトを作成することができます。
今回は、lambdaでgoを使っていくので、goのテンプレートを使用します。
@ueMac [~/dev]
[ueyuki]-> serverless create -u https://github.com/serverless/serverless-golang/ -p go-sqs-lambda
Serverless: Generating boilerplate...
Serverless: Downloading and installing "serverless-golang"...
Serverless: Successfully installed "serverless-golang"
必要なパッケージをgo getします。
@ueMac [~/dev/go-sqs-lambda]
[ueyuki]-> go get github.com/aws/aws-lambda-go/lambda
lambdaの実装
デフォルトで作成されたmain.goは以下のようになっています。
main.go
package main
import (
"github.com/aws/aws-lambda-go/lambda"
)
type Response struct {
Message string `json:"message"`
}
func Handler() (Response, error) {
return Response{
Message: "Go Serverless v1.0! Your function executed successfully!",
}, nil
}
func main() {
lambda.Start(Handler)
}
今回は、sqsから呼ばれて関数を実行したいため、以下のように変更します。
main.go
package main
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
type Response struct {
Message string `json:"message"`
}
func Handler(ctx context.Context, sqsEvent events.SQSEvent) error {
for i := range sqsEvent.Records {
record := sqsEvent.Records[i]
message := record.Body
fmt.Println(message)
}
return nil
}
func main() {
lambda.Start(Handler)
}
serverless.yml
serverless.ymlを設定します。
serverless.yml
service: go-sqs-lambda
provider:
name: aws
runtime: go1.x
stage: dev
region: ap-northeast-1
package:
exclude:
- ./**
include:
- ./bin/**
functions:
hello:
handler: bin/main
functions:
goQueueWorker:
name: go-queue-worker
handler: bin/go-handler
timeout: 30
memorySize: 1024
reservedConcurrency: 1
events:
- sqs:
arn: arn:aws:sqs:ap-northeast-1:{accountId}:go-queue
batchSize: 1
resources:
Resources:
MyQueue:
Type: "AWS::SQS::Queue"
Properties:
QueueName: "go-queue-by-serverless"
確認
まず、デプロイします。
@ueMac [~/dev/go-sqs-lambda]
[ueyuki]-> sls deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service go-sqs-lambda.zip file to S3 (6.22 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...
Service Information
service: go-sqs-lambda
stage: dev
region: ap-northeast-1
stack: go-sqs-lambda-dev
resources: 8
api keys:
None
endpoints:
None
functions:
goQueueWorker: go-queue-worker
layers:
None
Serverless: Removing old service artifacts from S3...
成功したようなので、メッセージを送ってみましょう。
@ueMac [~/dev/go-sqs-lambda]
[ueyuki]-> aws sqs send-message --queue-url https://ap-northeast-1.queue.amazonaws.com/434383646091/go-queue-by-serverless --message-body "ああああああああああああああああああああ"
{
"MD5OfMessageBody": "ea177a7ff3db26cb8928d1c895e873f1",
"MessageId": "37ebf278-519f-4438-8dee-e57f7072b131"
}
ログを確認してみると、
@ueMac [~/dev/go-sqs-lambda]
[ueyuki]-> sls logs -f goQueueWorker
START RequestId: a26e00fe-dbfb-56c4-b0c3-5764138a8ce4 Version: $LATEST
ああああああああああああああああああああ
END RequestId: a26e00fe-dbfb-56c4-b0c3-5764138a8ce4
REPORT RequestId: a26e00fe-dbfb-56c4-b0c3-5764138a8ce4 Duration: 0.40 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 25 MB
想定通り動いていそうです。