LoginSignup
7
0

More than 3 years have passed since last update.

AWS CLI で InvocationType が RequestResponse なのにLambda関数が複数回呼び出される

Posted at

TL;DR

--cli-read-timeout オプションで0を設定するか、呼び出すLambda関数のタイムアウト時間の秒数を指定する。

事象

Lambda関数で60秒を超える処理を行った際に AWS CLI で InvocationType が RequestResponse なのにLambda関数が複数回呼び出される。

原因

AWS CLI の lambda invoke はデフォルトでは60秒間でタイムアウトし5回まで再実行されるため。

確認

以下のようなLambda関数を用意します。指定した秒数、スリープで停止するLambda関数です。Lambda関数名は sleep とします。
タイムアウト時間は900秒(15分)にでも設定しておいてください。

import json
import time

print('Loading function')

def lambda_handler(event, context):
    print("Received event: " + json.dumps(event, indent=2))
    sleep_seconds = int(event.get("sleep", 3))
    time.sleep(sleep_seconds)
    return "sleep: {}s".format(sleep_seconds)

AWS CLI でLambda関数を実行します。65秒停止するよう指定します。
--debug オプションでデバッグログを出力しています。

aws lambda invoke \
   --function-name sleep \
   --invocation-type 'RequestResponse' \
   --payload '{"sleep":"65"}' \
   --debug \
   output.text

デバッグログを参照すると、接続タイムアウト設定を行なっていることが確認できます。

2020-07-10 10:26:47,915 - MainThread - botocore.endpoint - DEBUG - Setting lambda timeout as (60, 60)

さらにLambdaエンドポイントへ接続し、60秒後にタイムアウトが発生していることが分かります。

2020-07-10 10:26:47,938 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): lambda.ap-northeast-1.amazonaws.com:443
urllib3.exceptions.ReadTimeoutError: AWSHTTPSConnectionPool(host='lambda.ap-northeast-1.amazonaws.com', port=443): Read timed out. (read timeout=60)

タイムアウトでエラーとなると AWS CLI は再度Lambda関数を呼び出しています。

2020-07-10 10:27:49,004 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (2): lambda.ap-northeast-1.amazonaws.com:443

最大5回の実行が確認されました。

2020-07-10 10:30:52,431 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (5): lambda.ap-northeast-1.amazonaws.com:443

AWS CLI のレスポンスには以下が返ってきます。 output.text は出力されません。
尚、ここで2回目以降の実行が60秒以内に戻ってきた場合、正常終了のレスポンスが戻り output.text も正常に出力されるため、複数回呼び出されていることに気付きにくいことになります。

Read timeout on endpoint URL: "https://lambda.ap-northeast-1.amazonaws.com/2015-03-31/functions/sleep/invocations"

解決

--cli-read-timeout オプションを指定します。ここでは900秒を指定しましたが、0(無期限)でも構いません。

aws lambda invoke \
   --function-name sleep \
   --invocation-type 'RequestResponse' \
   --payload '{"sleep":"65"}' \
   --cli-read-timeout 900 \
   --debug \
   output.text

デバッグログを参照すると、接続タイムアウト設定に900秒が設定されていることが確認できます。

2020-07-10 10:42:16,834 - MainThread - botocore.endpoint - DEBUG - Setting lambda timeout as (60, 900)

AWS CLI のレスポンスも戻ってきて、output.text にも出力されています。

{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
output.text
"sleep: 65s"

参考

コマンドラインオプション
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-options.html

7
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0