はじめに
AWSでサーバレスアーキテクチャ構築しようとなったときに欠かせないのが AWSLambda ですよね。
基本的に他のサービスからのイベントでinvokeすることが多いと思いますが、その際 同期呼び出し でinvokeされるのか、 非同期呼び出し でinvokeされるのかを気にしたことはありますか?
今回は今更ではありますが、Lambdaがinvokeされるイベントが同期なのか、非同期なのかをまとめていこうと思います。
同期?非同期?
そもそも 同期 / 非同期 で、どんな違いがあるのでしょうか?
同期呼び出し
同期呼び出しの場合は直接Lambdaを 1回 実行します。
Lambdaが実行され、処理が完了してからレスポンスが返ってきます。
非同期呼び出し
非同期呼び出しの場合はLambdaを直接実行するわけではなく、キューイングされた後実行されます。
Lambdaの呼び出しに失敗した場合は自動的に2回までリトライされます。
キューイングされたタイミングでレスポンスが返ってきます。
呼び出しタイプのコントロール
AWSSDKやCLIからLambdaを実行する際に InvocationType
を指定することで同期呼び出し(RequestResponse
)するのか、非同期呼び出し(Event
)するのかをコントロールすることができます。
SDK(Node.js)で呼び出す例
exports.handler = async (event) => {
const lambda = new AWS.Lambda();
const params = {
FunctionName: "MyFunction",
InvocationType: "Event" // Event or RequestResponse or DryRun
}
await lambda.invoke(params).promise();
};
ですが、Lambdaトリガーになりうるイベントに対して、その呼び出しタイプが同期なのか非同期なのかは基本的に予め決められています。
例えばS3トリガーは非同期、Cognitoトリガーは同期。といった感じです。
同期呼び出しのトリガー
- APIGateway (デフォルト)
- Cognito
- Alexa
- Lex
非同期呼び出しのトリガー
- APIGateway (ヘッダーでEventを指定した場合)
- AWSIoT
- CloudWatch Events
- CloudWatch Logs
- CodeCommit
- S3
- SNS
- SES
- KinesisFirehose
- CloudFormation
- AWSConfig
ポーリングするトリガー
実は同期呼び出しでも非同期呼び出しでもないトリガーがあります。
Lambda側から定期的にポーリングして、新しいイベントがあれば処理を実行します。
Lambda側からイベントを取得しに行くので、もちろんそのためのIAMRoleが必要です。(kinesis:GetRecords
とか kinesis:GetShardIterator
とかとか……)
ちなみにKinesisDataStreamsは毎秒1回、DynamoDBStreamsは毎秒4回ポーリングをします。
SQSはトリガーごとにポーリング間隔等を設定します。
- KinesisDataStreams
- DynamoDBStreams
- SQS
さいごに
今まで、 同期呼び出し や 非同期呼び出し があることは知っていましたが、改めてまとめてみて再確認できました。
あまり意識することは無いと思いますが、「なんで複数回実行されてるんだ?」といった現象に出くわした際は、呼び出し方のことを思い出してください。そのLambdaの実行…同期呼び出しかもしれませんよ?
ではまた!!!