Amazon EventBridge Scheduler のフレックスタイムウィンドウを利用したサーバーレスなスケジューラーの使い方
堀家 隆宏 (AWS Serverless HERO)
昨年発表された AWS 新サービス、新機能の中でも話題になったのが Amazon EventBridge 関連のアップデートだったかと思います。EventBridge Pipes のような新機能も大きく注目を集めましたが、他にもいくつか便利な新機能が追加されており、その中の一つが EventBridge Scheduler です。
このクラウドレシピ (ハンズオン記事) を無料でお試しいただけます »
毎月提供されるクラウドレシピのアップデート情報とともに、クレジットコードを受け取ることができます。
EventBridge Scheduler によって、任意の時刻を指定してイベントを配信する機能を AWS のサービスとして利用することが可能になりました。特に、その中でも私が注目したいのがオプション機能の「フレックスタイムウィンドウ」です。このオプションをオフにすると、指定された時間 (※分単位) に一度限り配信 (※at-least-once) されます。このオプションをオンにすると、指定された時間とフレックスタイムウィンドウの時間内のどこかのタイミングで配信されるようになります。仮に、12 時配信のスケジュールを登録し、フレックスタイムウィンドウを15分に指定した場合、12 時から12 時 15 分の間のどこかで配信される仕組みになります。
以下のように、コンソールからフレックスタイムウィンドウの設定が確認できます。フレックスタイムウィンドウをオンにする場合、15 分・30 分・1 時間・2 時間・4 時間を指定することが可能です。
クリックすると拡大します
指定した時間に一度限りのイベントを配信する
まずはフレックスタイムウィンドウをオフにして時間通りに起動できるか確認してみます。コンソールで指定することもできますし、AWS CLI や AWS SDK を利用して簡単なスケジュールを以下のように登録することも可能です。スケジュールイベントの配信先には動作確認で AWS Lambda 関数を登録しておきます。
await scheduler.createSchedule({
Name: 'Testing_One_Time_1',
FlexibleTimeWindow: { 'Mode': 'OFF' },
ScheduleExpression: 'at(2023-03-04T19:50:00)', // 「分単位」で反映されます
Target: {
Arn: '{配信先Lambda関数のARN}',
RoleArn: '{配信先Lambda関数を呼ぶためのポリシーを持つスケジューラーのロール}',
Input: JSON.stringify({ message: 'testing purpose' })
},
ScheduleExpressionTimezone: 'Asia/Tokyo'
}).promise()
こちらのようにコンソールでも登録されたスケジュールが確認できます。
クリックすると拡大します
時間通りに Lambda が起動されているか、ログのタイムスタンプを確認します。2 回起動を試していて、いずれの場合も指定した時間通り (19:50, 21:10) に届いていることが分かります。
クリックすると拡大します
スケジュール一覧では一度実行が済んだスケジュールでも残り続けるため、at を指定して再利用することがなければ、適宜削除していく必要があります。また注意点としては、一度限り配信でも「at-leastonce」なので 2 回以上配信される可能性がある点と、指定時間は分単位となるため、秒単位まで合わせて起動させるためには別のアーキテクチャを利用する必要があります。
これらの問題に関しては、AWS Step Functions を利用したスケジューラのアーキテクチャを builders.flash に投稿 しておりますので、合わせて確認してみてください。
指定した時間内に分散してイベントを配信する
フレックスタイムウィンドウをオンにするユースケースは様々あると思います。その中でも一つ考えられるのが、分散型システムとして大量のイベント通知をセグメンテーションして時間差をおいて分散して送信する必要がある場合です。
例えば、数万件のメッセージを一斉に配信する場合、配信サービスのクォーターやレートリミットに引っかかったり、通知を受け取ったユーザーがアプリを開いてセッションを作成する処理のスパイクが想定される場合があります。そうすると、一定間隔をおいて少しずつ切り刻まれた量のメッセージを送信していく必要があります。
< AWS Step Functionsを使用する例 >
< Amazon SQS を使用する例 >
しかし、新しくアップデートされたフレックスタイムウィンドウを利用すると、以下のようにスケジュールを登録することで、分散して配信を行うことが可能です。
const groups = [ 'A', 'B' , 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' ]
for (let i = 1; i <= 10; i++) {
await scheduler.createSchedule({
Name: `Testing_Flexible_Time_15min_${i.toString()}`,
FlexibleTimeWindow: {
Mode: 'FLEXIBLE',
MaximumWindowInMinutes: 15
},
ScheduleExpression: 'at(2023-03-05T09:00:00)',
Target: { /* required */
Arn: '{配信先Lambda関数のARN}',
RoleArn: '{配信先Lambda関数を呼ぶためのポリシーを持つスケジューラーのロール}',
Input: JSON.stringify({ message: 'testing purpose', group: groups[i - 1] })
},
ScheduleExpressionTimezone: 'Asia/Tokyo'
}).promise()
}
オフのときと同じように、配信先には Lambda 関数を指定して実際に配信されたタイムスタンプを確認します。15 分の結果では以下のようにばらつきが見られます。
フレックスウィンドウタイムの間隔を伸ばしていくとイベントが配信される間隔はより広がりますので、厳密に時間指定を行わず処理を分散したい場合、有効に使えるオプションです。時間指定には at 以外でも cron , rate を含め 3 つの方法があり、状況や要件に合わせて使い分けていくと良いかと思います。
まとめ
このように EventBridge Scheduler とフレックスタイムウィンドウオプションを応用することで、サーバーレスなスケジューラーとして色んなユースケースに対応することが可能です。また、配信のタイミングを制御するための構成もシンプルになり、前項 で紹介したような AWS Step Functions のワークフローを構築したり、Amazon SQS を挟む非同期処理のフローを組むことなく、EventBridge というサービス一つで解決できるため、アーキテクチャの複雑性を軽減する効果もあります。
この機会に是非導入してみてはいかがでしょうか。
筆者プロフィール
堀家 隆宏
AWS Serverless HERO / 株式会社Serverless Operations
2014 年に AWS Lambda がリリースされてから、手軽にコードがデプロイでき、素早く動くものが出来るサーバーレスのコンセプトに惹かれて、サーバーレスのファンに。それからは JAWS-UG やサーバーレスコミュニティなどの活動を経て、2021 年に AWS の Serverless Hero に認定されました。
仕事においても Serverless Operations という会社を 2018 年に設立して、エンタープライズ企業からスタートアップまで、様々な業種の企業様にサーバーレスを中心とした内製化・開発支援のサービスに従事しています。
AWS を無料でお試しいただけます