同期処理におけるAWS Lambda関数タイムアウトのハンドリング検討

背景
弊社ではサーバーレスアーキテクチャを活用した開発を進めており、AWS Lambdaも多くのプロジェクトで利用しています。しかし、Lambda関数のタイムアウトが発生した場合のハンドリングが不十分で、サービスの一時的な停止や、顧客体験の低下に繋がる事例が発生しました。本記事では、Lambda関数のタイムアウトに対する適切なハンドリング方法を検討し、より信頼性の高いシステム構築を目指します。
検証概要
- API Gateway + Lambda構成
- クライアント(frontend)からのリクエスト時にタイムアウトするケースを想定し、ハンドリングを検討
- Lambda関数から同期で他のLambda関数を実行
- バックエンドでの実行時にタイムアウトするケースを想定し、ハンドリングを検討
検証1: API Gateway + Lambda構成
再現するタイムアウトの設定
以下のLambda関数を30秒のタイムアウト設定で実装しました。この関数は、45秒間スリープするため確実にタイムアウトが発生します。
import json import time def lambda_handler(event, context): print('=====sleep start=====') time.sleep(45) print('=====sleep end=====') return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }
実験内容
この関数をAPI Gatewayで GET /time-out エンドポイントとして公開し、以下のコマンドでリクエストを実行しました。
curl https://your.domain/time-out -i
結果
タイムアウトが発生した場合、以下のレスポンスが返ってきました。
HTTP/2 504 date: Sat, 07 Dec 2024 12:51:53 GMT content-type: application/json content-length: 41 x-amzn-requestid: de0b98ff-54cb-46af-acb3-d3d3f08dd189 x-amzn-errortype: InternalServerErrorException x-amz-apigw-id: Ca-v-EJmoAMEpqw= {"message": "Endpoint request timed out"}
クライアント側の対応策
タイムアウトに対してクライアント側で考えられる対応策は以下の通りです。
-
リトライの実装
タイムアウトが一時的である可能性があるため、504エラー時にリトライを実施する。
-
調査用情報の活用
x-amzn-requestidとx-amz-apigw-idを取得し、ログや通知システムに保存。これらの情報はCloudWatch Logsでの調査に役立つ。
-
アラート設定
頻繁にタイムアウトが発生する場合にはアラートを送信し、開発チームに早期対応を促す。
検証2: Lambda関数から同期で他のLambda関数を実行
呼び出し元関数
以下の呼び出し元関数を1分のタイムアウト設定で実装しました。この関数から、タイムアウトが設定された別のLambda関数を同期的に実行します。
import json import boto3 def lambda_handler(event, context): lambda_client = boto3.client('lambda') function_name = 'TimeOut' response = lambda_client.invoke(FunctionName=function_name) print('=====print response start=====') print(response) print('=====print response end=====') return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }
実験結果
呼び出し先のLambda関数がタイムアウトすると、以下のようなレスポンスが返りました。
{ 'ResponseMetadata': { 'RequestId': '36337419-d972-4d5b-b08e-b5f125859dcb', 'HTTPStatusCode': 200, 'HTTPHeaders': { 'x-amzn-requestid': '36337419-d972-4d5b-b08e-b5f125859dcb', 'x-amz-function-error': 'Unhandled', 'x-amzn-trace-id': 'Root=1-675449fe-3bb52bbf04bfa28c7dc64c26' } }, 'FunctionError': 'Unhandled', 'Payload': {'errorMessage': 'Task timed out after 30.02 seconds'} }
呼び出し元の対応策
-
エラー情報のチェック
FunctionErrorの存在やPayloadを解析し、タイムアウトが原因かを判断する。タイムアウトが原因の場合、リトライ処理を検討する。 -
ログの活用
x-amzn-requestidをエラー情報として記録。呼び出し先関数のログ調査時に役立つ。x-amzn-trace-idを記録。X-Rayを活用したトレーシングでシステム全体の動作を追跡可能。
-
アラート設定
タイムアウトの頻度が高い場合、アラートを設定し、異常検知の迅速化を図る。
結論
AWS Lambdaのタイムアウト問題は、適切にハンドリングすることでシステムの信頼性を高めることができます。本記事で紹介した方法を参考に、以下のポイントを意識した対策を行いましょう。
-
リトライ戦略の実装
一時的な問題であれば、リトライで解決する場合があります。
-
ログの充実化
調査に役立つリクエストIDやトレースIDをエラーログとして記録。
-
アラートと通知
問題が発生した際には迅速に開発チームが対応できるような仕組みを構築。
-
設計の見直し
タイムアウトの根本原因(処理時間が長すぎるなど)を分析し、コードやシステム構成の改善も検討する。
AWS Lambdaの柔軟性を活かしつつ、堅牢で信頼性の高いシステムを構築していきましょう!
この記事をシェアする
合同会社raisexでは一緒に働く仲間を募集中です。
ご興味のある方は以下の採用情報をご確認ください。