📝

SQS FIFO キューをトリガーにもつ Lambda がタイムアウトになった際の挙動を確認してみた

に公開

以下の挙動でした。

  • 同じメッセージの処理をリトライし続ける
  • リトライ処理は最初から実行される
  • 処理中のメッセージがある場合には後続のメッセージは処理されない

検証内容

  • SQS FIFO キュー: デフォルト設定で作成

  • Lambda 関数

    • ランタイム: Python 3.13
    • 実行ロール: AdministratorAccess 権限を付与
    • トリガー: SQS FIFO キューをデフォルト設定で指定
    • タイムアウト: 10 秒

Lambda 関数のコードは以下の通りです。

import json
import time
import logging

# ログ設定
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info("=== Lambda処理開始 ===")
    logger.info(f"受信したイベント: {json.dumps(event, ensure_ascii=False)}")
    
    # SQSレコードを処理
    for record in event['Records']:
        message_id = record['messageId']
        body = record['body']
        receipt_handle = record['receiptHandle']
        
        logger.info(f"メッセージID: {message_id}")
        logger.info(f"メッセージ内容: {body}")
        logger.info("処理を開始します...")
        
        # 意図的に長時間処理をシミュレート(15秒間待機)
        # Lambda のタイムアウト(10秒)より長く設定
        for i in range(15):
            time.sleep(1)
            logger.info(f"処理中... {i+1}/15秒経過")
        
        logger.info("処理完了")
    
    logger.info("=== Lambda処理終了 ===")
    return {
        'statusCode': 200,
        'body': json.dumps('処理完了')
    }

上記設定後、SQS コンソールからメッセージを送信しました。

Lambda の実行ログは以下の通りです。

2025-07-18T04:34:36.732Z
[INFO] 2025-07-18T04:34:36.732Z 2a108ffd-af5f-5695-a084-ef0e7e56729a メッセージ内容: テストメッセージ1 - タイムアウト検証用
2025-07-18T04:34:36.732Z
[INFO] 2025-07-18T04:34:36.732Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理を開始します...
2025-07-18T04:34:37.733Z
[INFO] 2025-07-18T04:34:37.732Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理中... 1/15秒経過
2025-07-18T04:34:38.733Z
[INFO] 2025-07-18T04:34:38.733Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理中... 2/15秒経過
2025-07-18T04:34:39.733Z
[INFO] 2025-07-18T04:34:39.733Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理中... 3/15秒経過
2025-07-18T04:34:40.733Z
[INFO] 2025-07-18T04:34:40.733Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理中... 4/15秒経過
2025-07-18T04:34:41.734Z
[INFO] 2025-07-18T04:34:41.734Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理中... 5/15秒経過
2025-07-18T04:34:42.734Z
[INFO] 2025-07-18T04:34:42.734Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理中... 6/15秒経過
2025-07-18T04:34:43.734Z
[INFO] 2025-07-18T04:34:43.734Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理中... 7/15秒経過
2025-07-18T04:34:44.735Z
[INFO] 2025-07-18T04:34:44.735Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理中... 8/15秒経過
2025-07-18T04:34:45.735Z
[INFO] 2025-07-18T04:34:45.735Z 2a108ffd-af5f-5695-a084-ef0e7e56729a 処理中... 9/15秒経過
2025-07-18T04:34:46.738Z
END RequestId: 2a108ffd-af5f-5695-a084-ef0e7e56729a
2025-07-18T04:34:46.738Z
REPORT RequestId: 2a108ffd-af5f-5695-a084-ef0e7e56729a Duration: 10000.00 ms Billed Duration: 10000 ms Memory Size: 128 MB Max Memory Used: 35 MB Status: timeout

タイムアウト後、上記のログが連続で出力されており、同じメッセージ ID のメッセージに対する処理を繰り返していました。
これは、以下の流れによるものであると思われます。

  1. Lambda が SQS キューをポーリングしてメッセージを取得
  2. Lambda でエラーが発生したためメッセージがキューに戻る
  3. キューの可視性タイムアウト後にメッセージが再度キューに表示される
  4. 再度 Lambda がキューのメッセージを取得

Amazon SQS イベントソースマッピングの作成と管理 - AWS Lambda

関数が正常にバッチを処理すると、Lambda はキューからそのメッセージを削除します。
...
デフォルトでは、Lambda がバッチを処理しているときにエラーが発生すると、そのバッチ内のすべてのメッセージがキューに戻ります。可視性タイムアウトの後、メッセージは再び Lambda に表示されるようになります。

上述の通り、Lambda でのエラー発生時にメッセージは削除されずにキューに戻るため、ループのような挙動になったと思われます。

なお、1 回目の Lambda 実行についてはコールドスタートでしたが、2 回目以降はウォームスタートでした。

2 つ目のメッセージを追加してみる

上記のループ状態で SQS キューに 2 つ目のメッセージを追加しました。

結果としては 1 つ目のメッセージの処理が繰り返され、2 つ目のメッセージについては処理されませんでした。
ただし、FIFO キューからのメッセージ取得の場合、Lambda は複数のメッセージグループを並列処理するようスケールアップできるため、メッセージグループが複数ある場合には 2 つ目のメッセージも処理される可能性があります。

Amazon SQS の FIFO キューと Lambda の同時実行動作 - Amazon Simple Queue Service

ただし、複数のメッセージグループを並列処理するようにスケールアップできるため、キューのワークロードを効率的に処理できます。

まとめ

今回は SQS FIFO キューをトリガーにもつ Lambda がタイムアウトになった際の挙動を確認してみました。
どなたかの参考になれば幸いです。

参考資料

Discussion