はじめに
しばらく利用していなかったAPIをコールした際に、BackendのLamdbaが呼ばれることなく、500エラーが返ってくる事象に遭遇しました。
今回はこの事象について調査してみます!
なお、この事象に遭遇した環境はAPI Gateway(REST) + Lambda(Java,SnapStart有)の構成です。
結論
Java + SnapStartの構成のみ、2週間以上呼び出しをしないと、次回呼び出し時にエラーが発生します。
For functions using a Java runtime, Lambda deletes snapshots after 14 days without an invocation. If you invoke the function version after 14 days, Lambda returns a SnapStartNotReadyException response and begins initializing a new snapshot. Wait until the function version reaches the Active state, and then invoke it again.
・・・とのことです。
スナップショットを作るまで待つとかはしてくれず、エラーとなってしまう困った仕様です。
色々確認。
事象を確認するために、色々確認してみます。
API Gatewayのログ
この事象が起きた際、Lambda側のログはありませんでした。
API Gatewayのログは残っていたので、確認すると以下のようになってました。
抜粋します。
Lambda invocation failed with status: 409.
409については、以下に説明がありました。
SnapStartNotReadyException
であることが確認できます。
Execution failed due to configuration error: Lambda is initializing your function.It will be ready to invoke once your function state becomes ACTIVE.
``
このメッセージも、Lambdaは関数を初期化していて、関数の状態がACTIVEになれば、実行できるようになる旨の内容なので記事の通りですね。
再作成の確認
ソフトウェアアップデートのために行う、スナップショット再作成の挙動も確認してみます。
ログを見てみると、定期的にSpringの起動ログが表示されてアプリの起動のみを行なっているようなログがありました。
これがスナップショットの再作成と考えて良さそうです。
ランタイムの更新や、スナップショット上にある陳腐化する認証情報・接続情報の更新とかをしてそうです。
作成周期を見てみると、2025/02/07の最後の実行の後から、それぞれ以下のような周期で作られていました。
- 2025/02/11
- 2025/02/12(1日後)
- 2025/02/13(2日後)
- 2025/02/18(5日後)
エクスポネンシャルバックオフ(指数関数的退行)みたいな感じで、最後の実行から1週間近くまでは再作成がされていました。
構成
私のプライベート用アカウントで最近使っていないAPI Gateway+Lambdaの構成をしたAPIでいくつか確認してみました。
API Gateway(REST) + Lambda(Python + Snapstart無)
こちらは、再現しませんでした。
やはり、SnapStartを起因とした問題のようです。
API Gateway(HTTP) + Lambda(Java21 + Snapstart有)
再現しました!
HTTPなので、詳細なログやX-Rayが利用できずアクセスログのみですが、しばらく500エラーが発生していることを確認しました。
2分経過したくらいにきちんと動くようになってましたので、スナップショットを作っている時間と考えて良さそうです。
{
"requestId": "Kkr8igNbNjMEPHQ=",
"ip": "xxx.xxx.219.227",
"requestTime": "14/May/2025:19:48:19 +0000",
"httpMethod": "GET",
"routeKey": "$default",
"status": "500",
"protocol": "HTTP/1.1",
"responseLength": "35"
}
SnapStartを起因とした問題なので、RESTかHTTPかはもちろん関係なしです。
関数ステータス
以下コマンドで関数ステータスを確認できるので、実際に2週間以上呼ばれていないラムダ関数の状態を確認してみます。
aws lambda get-function --function-name [関数名:エイリアス] --query 'Configuration.[State, LastUpdateStatus]'
まずは既に利用可能なものLambdaでは、Active
となってました。
[
"Active",
"Successful"
]
次にエイリアスに紐付くバージョンを一つ下げることで、2週間以上使っていないスナップショットを利用できるので、この方法で試してみます。
[
"Inactive",
"Successful"
]
Inactive
となっています。想定通りですね。
直接コールしてみる。
最後にAPI Gatewayを経由せず、直接Lambdaをコールしてみます。
Lambda is initializing your function.It will be ready to invoke once your function state becomes ACTIVE.
こちらもACTIVE
になるまで待てといった内容です。
最後に
色々検証して、記事の通りで間違いなさそうなことがわかりました。
サービスインの2週間以上前に本番リリースをしておく、といったケースで遭遇しそうなので、記事に残しておきました!
誰かのお役に立てると嬉しいです!