はじめに
AWS で予約実行や定期実行などのスケジュール処理を実装する場合に、Amazon EventBridge を使用してスケジュールベースのルールを組むことはプラクティスの 1 つだと思います。しかしながら、Amazon EventBridge を使ったスケジュール処理には以下のような課題があります。
予約時刻から数分程度ズレで実行される場合がある
AWS Lambda を実行する場合に非同期呼び出しとなるため、複数起動される場合がある
これらが許容される場合は特に問題がありませんが、許容できない場合には AWS Step Functions を使うことで正確な時刻での配信が出来るスケジューラーを構築することが出来ます。
なお、以下の GitHub でソースコードは公開していますので興味がある方は是非触ってみてください。
ご注意
本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。
builders.flash メールメンバー登録
1. アーキテクチャ
2. スケジュール実行までの流れ
3. Amazon DynamoDB のテーブル設計
テーブル設計も見ていきましょう。大きなデータの種別としては以下の 2 種類になっています。それぞれデータの PK の最初の文字列でデータの種別を表現しています。
INVOKER#<invoker name> : スケジュール実行される AWS Lambda の情報を格納
MESSAGE#<message ID> : 配信されるメッセージ。予約時刻やステータス、スケジュール実行時のパラメータ情報を格納
PR |
ARN |
GSI1PK |
GSI1SK |
Parameter |
InvokerID |
PublishDate |
INVOKER#invoker-alpha |
arn:aws:lambda:ap-northeast-1:xxxxxxxxx:function:xxxxxx |
|||||
INVOKER#invoker-beta |
arn:aws:lambda:ap-northeast-1:xxxxxxxxx:function:yyyyyy |
|||||
MESSAGE#a7ddf672-409d-4f1e-927d-2221aa0f5ba0 |
MESSAGE#STANDBY |
MESSAGE#1646815555 |
{"message":"Invocation test from invoker-alpha"} |
invoker-alpha |
1646815555 |
|
MESSAGE#5f8d99e5-afa5-4268-976d-3a028396872e |
MESSAGE#RESERVED |
MESSAGE#1647127900 |
{"message":"Invocation test from invoker-alpha"} |
invoker-alpha |
1647127900 |
|
MESSAGE#015eadee-1a2f-48e1-8f1e-debcd67ec08b |
MESSAGE#DONE |
MESSAGE#1646782800 |
{"message":"Invocation test from invoker-alpha"} |
invoker-alpha |
1646782800 |
RESERVED ステータスのデータ取得
更に予約スタンバイが RESERVED のメッセージを検索できるように Global Secondary Index を作っており、以下のような Query で RESERVED ステータスのデータを取得してステータスをアップデートしています。
const queryCmd = new QueryCommand({
TableName: this.reservationTableName,
IndexName: ‘GSI1',
KeyConditionExpression: '#gsi1pk = :gsi1pk AND #gsi1sk < :gsi1sk’,
ExpressionAttributeNames: {
'#gsi1pk': ‘GSI1PK',
'#gsi1sk': ‘GSI1SK',
},
ExpressionAttributeValues: {
':gsi1pk': { S: ‘MESSAGE#RESERVED’ },
':gsi1sk': { S: `MESSAGE#${searchTimestamp}`},
},
});
4. 動作確認

Curl で配信メッセージを登録
Curl で配信メッセージを登録します。2022/03/09 18:40 に Invocation test from invoker-alpha というメッセージが配信されるように設定しています。
curl --location --request POST '<https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/messages>' \\
--header 'Content-Type: application/json' \\
--data-raw '{
"publishTime": 1646818800,
"channel": "invoker-alpha",
"parameters": {
"message": "Invocation test from invoker-alpha"
}
}'
ステータスの確認
5. まとめ
以上のように AWS Step Functions を使うことで時間丁度に実行が行えるスケジューラーを構築することが出来ました。この構成は Amazon EventBridge において配信時刻がずれる問題や冪等性への配慮を解決します。また、今回使用した AWS Step Functions のスタンダートタイプは東京リージョンで、状態遷移 1,000 回ごとの料金が 0.025 USD (無料枠 4,000 回の状態遷移/月, 2022/03/11 現在) であり、大量の予約配信を実施するような場合は Amazon EventBridge と比較するとコスト面での注意は必要です。
それを差し引いてもメリットがあるケースでは有効なアーキテクチャではないでしょうか。特に一度構築してしまえば、AWS Lambda 内のライブラリ等のアップデート以外はメンテナンスの必要はありませんし、ほとんど手離れで運用できるシステムとも言えるでしょう。これはサーバーレスアーキテクチャを採用する上で大きなメリットの 1 つと言えます。
筆者プロフィール
堀家 隆宏
株式会社Serverless Operations
2014 年に AWS Lambda がリリースされてから、手軽にコードがデプロイでき、素早く動くものが出来るサーバーレスのコンセプトに惹かれて、サーバーレスのファンに。それからは JAWS-UG やサーバーレスコミュニティなどの活動を経て、2021 年に AWS の Serverless Hero に認定されました。
仕事においても Serverless Operations という会社を 2018 年に設立して、エンタープライズ企業からスタートアップまで、様々な業種の企業様にサーバーレスを中心とした内製化・開発支援のサービスに従事しています。

Did you find what you were looking for today?
Let us know so we can improve the quality of the content on our pages