はじめに
こちらでははじめまして!
SimSta(しむすた)と申します。
普段は個人ブログ「しまがじ!」で、AWSのアップデートを毎週まとめるなどしています。
しまがじ! 〜ホワイトシマリス飼いのガジェットブログ〜
※ガジェットブログなのにまだガジェット記事が1個しかありません
うちの子も見てってね。
API Gatewayのアップデート
早速ですが、2024/6/5に以下のアップデートがありました。
概要
API GatewayでRESTのRegional APIまたはPrivate APIを使用している場合、統合リクエストのタイムアウトがデフォルトの29,000ミリ秒(29秒)から延長可能になったというものです。
たとえばLambdaを同期的に呼び出したとき、処理が30秒以上かかる場合はタイムアウトしてしまうため、29秒以内に収めるか、実行だけをトリガーしてポーリングするなどの実装が必要でした。
特に生成AIでエージェントを実行する関数とかだと普通に30秒以上かかってしまいそうですよね。
今回のアップデートで、同期的に呼び出した際にも30秒以上待つことができるようになったということです。
リクエストの結果によっては、スロットルクォータ制限が引き下げになる可能性が示唆されています。本番アカウントで無闇に大きい値をリクエストするとワークロードに影響しますのでご注意ください。
どうすれば延長できるの?
Service Quotaからリクエストできます。
「timeout」でフィルタすると1番目に出てくるので、選択して「アカウントレベルでの引き上げをリクエスト」をクリックすることで希望の値をミリ秒単位で設定できます。
リクエストはリージョン単位(複数リージョンの場合はリージョンごとに申請が必要)です。
実際にリクエストしてみた
アップデートを見て、早速リクエストしてみました!
値としては、 バージニア北部で300,000ミリ秒(300秒)、オレゴンで900,000ミリ秒(900秒) です。
おそらくみんな承認待ちなため、これが(きっと)宇宙最速のアウトプットです!
なお、今日(2024/6/14)確認した所、以下のInfoが追加されていました。
自動承認の基準がわかりませんが、今回は大きいリクエストとみなされていたようで、どちらのリクエストもサポートケースに送信されました。
サポートでやり取り
これが長かった…
2024/6/14時点でバージニア北部(300秒)のリクエストが完了しているため、こちらをもとにタイムラインを紹介します。
2024/6/5 リクエスト送信
サポートケースが作成されました。
2024/6/6 一次回答
「2〜3日待ってね!」と返答が来ました。
2024/6/8 続報
「もう2〜3日待ってね!」と返答が来ました。
2024/6/9 追加のリクエストあり
ここで、簡単なユースケースの送信を求められました。
特に何もユースケースを考えてなかったのでOpusに聞きながら 以下の通り入力しています。
なお、おそらく担当する人によって質問内容が若干異なるようです。具体的なワークロードの説明を用意しておいたほうが良いでしょう。
- HTTP APIですか?
→ REST APIです - Regional APIですか?
→ Regional APIです - この統合におけるRPSはどのくらいですか?
→ 1〜5くらいです - アカウント全体におけるRPSはどのくらいですか?
→ 5〜25くらいです - 呼び出しにおける p50, p90, p99 latencyはどのくらいですか?
→ それぞれ100秒, 200秒, 300秒くらいです - リクエストのペイロードサイズはどのくらいですか?
→ 10〜50KBくらいです
※2日半ほど放置してしまい、実際に送信したのは2024/6/12でした
2024/6/13 返答あり
「提供ありがとう!有効になったらお知らせするからちょっと待ってね!」と返答が来ました。
2024/6/14 リクエスト承認!
ようやくリクエストが承認されました!
コンソールからも300,000ミリ秒になったことが確認できました。
リクエストからのタイムラインまとめ
(こちらのユースケース送信保留を除くと)実質7日ほどでの承認となりました。
なお、オレゴンの900秒リクエストはちょうどユースケースの提供を求められているところです。
アップデート直後だった点、リクエストの値が大きかった点から時間がかかったものと思われるため、タイミングや値によってはもう少し短い期間で承認されそうです。
簡単に試してみた
実際にAPI GatewayとLambdaを使って試してみました。
Lambdaを作成
以下のPythonコードをOpusに作ってもらいました。
Lambda自身のタイムアウトを延長するのを忘れずに!
import json
import time
def lambda_handler(event, context):
# リクエストパラメータから実行時間(秒)を取得
execution_time = int(event.get('queryStringParameters', {}).get('execution_time', 45))
# 開始時刻を記録
start_time = time.time()
# 指定された実行時間だけ待機
while time.time() - start_time < execution_time:
time.sleep(1)
# 実行時間を計算
actual_execution_time = int(time.time() - start_time)
# レスポンスを返す
response = {
'statusCode': 200,
'body': json.dumps({
'message': f'Lambda function executed for {actual_execution_time} seconds.'
})
}
return response
API Gatewayを作成して統合
何の変哲も無いREST APIを作成します。構築の詳細は省略します。
リソースは「timeouttest」として作成しました。
タイムアウトを29秒以内で設定しろと言われますが、300秒で通るようになっています。
マッピングテンプレートを以下のようにします。これで、URLからパラメータとして秒数を指定できます。
{
"queryStringParameters": {
"execution_time": "$input.params('execution_time')"
}
}
これをprodステージにデプロイすることで、呼び出せるようになります!
実際に呼び出してみた
呼び出しURLは以下のようになります。
最後の「execution_time=60」に任意の秒数を指定する形です。
指定しない場合、デフォルトは先程のLambdaで45秒と指定しています。
https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/prod/timeouttest?execution_time=60
これをブラウザやcurl等で呼び出すことで、60秒後にレスポンスが帰ってきます!
Chromeで呼び出した場合はこんな感じです。ちゃんとAPI Gatewayがタイムアウトせずに実行できていますね。
でも結局そんな長いタイムアウト要る?
あんま要らないかなあ…
少なくとも新規で開発する際には、同期的にLambdaを呼び出すよりは非同期でアーキテクチャを実装するほうが多くのメリットを享受できます。
この辺りは詳細な説明を省略しつつ、ちょうど来週のAWS Summit Japan Day2にてServerlessスペシャリストの下川さんがお話されるので、是非こちらをご覧ください!
またStep Functionsと統合すれば、呼び出しを行うStartExecution APIが非同期なので自ずと非同期に構成することができます。
おわりに
Step Functionsはいいぞ。