调用另一个(长)Lambda时,AWS Lambda超时

时间:2018-12-22 19:56:39

标签: amazon-web-services aws-lambda aws-sdk

我正在使用将多个Lambda链接在一起的步进函数。在这些Lambda之一中,我调用了另一个Lambda。两个Lambda都有15分钟的超时时间。但是,在经过几分钟后,调用次要Lambda的主要Lambda会超时(次要Lambda会愉快地继续其工作)。

Error

com.amazonaws.SdkClientException
Cause

{"errorMessage": "Unable to execute HTTP request: Read timed out",
  "errorType": "com.amazonaws.SdkClientException",
  "stackTrace": [
    cause": {
      "errorMessage": "Read timed out",
   "errorType": "java.net.SocketTimeoutException",
   "stackTrace": [
  "java.net.SocketInputStream.socketRead0(Native Method)",
  "java.net.SocketInputStream.socketRead(SocketInputStream.java:116)",
  "java.net.SocketInputStream.read(SocketInputStream.java:171)",
  "java.net.SocketInputStream.read(SocketInputStream.java:141)",
  "sun.security.ssl.InputRecord.readFully(InputRecord.java:465)",
  "sun.security.ssl.InputRecord.read(InputRecord.java:503)",
  "sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)",
  "sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:940)",
  "sun.security.ssl.AppInputStream.read(AppInputStream.java:105)",

这是代码,如您所见,我尝试使用4个不同的命令来提高超时时间。

  // (2) Instantiate AWSLambdaClientBuilder to build the Lambda client
        AWSLambdaClientBuilder builder = 
 AWSLambdaClientBuilder.standard().withRegion(region);
        // (3) Build the client, which will ultimately invoke 
   the function
        AWSLambda client = builder.build();

        // (4) Create an InvokeRequest with required parameters
        InvokeRequest req = new 
   InvokeRequest().withFunctionName(random_arn).withPayload(jsonString); 

        // (5) Invoke the function and capture response
        int timeout = (15*60*1000);
        req.setSdkClientExecutionTimeout(timeout);
        req.setSdkRequestTimeout(timeout);
        req.withSdkClientExecutionTimeout(timeout);
        req.withSdkRequestTimeout(timeout);

        InvokeResult result = client.invoke(req);

有什么办法解决这个超时问题吗?

2 个答案:

答案 0 :(得分:2)

由于您未明确指定调用类型,因此您将从第一个AWS Lambda中同步调用第二个AWS Lambda函数。因此,当您的第二个AWS Lambda函数正在运行时,第一个函数也将继续运行,等待第二个函数的响应。因此,如果第一个和第二个AWS Lambda函数的运行时间之和大于第一个AWS Lambda函数的已配置最大超时(在您的情况下为15分钟),则第一个AWS Lambda函数将超时。 >

从另一个AWS Lambda函数同步调用AWS Lambda函数是一种不好的做法,因为您可能会遇到超时问题,因为您现在遇到这种情况,并花钱在运行第二个AWS Lambda函数时运行第一个AWS Lambda函数。

您可以做的是通过setting the proper invocation type为您的InvokeRequest异步调用第二个AWS Lambda函数:

InvokeRequest req = new InvokeRequest().withFunctionName(random_arn)
                                       .withPayload(jsonString)
                                       .withInvocationType(InvocationType.Event); 

当然,只有在不依赖第二个AWS Lambda函数的输出来完成第一个函数的情况下,这才起作用。

正如您已经在使用AWS Step函数一样,可能更好的选择是使用Step Functions状态机来协调第二个AWS Lambda函数的调用,如以下教程所述:https://aws.amazon.com/de/getting-started/tutorials/create-a-serverless-workflow-step-functions-lambda/ < / p>

根据您的AWS Lambda的功能方式,将第一个AWS Lambda函数拆分是有意义的,该功能目前正在将第二个AWS Lambda函数分为在调用的Lambda函数之前和之后运行的两个部分。

答案 1 :(得分:1)

使用AWS Lambda时,您可能会感兴趣多个超时。您要指的是函数执行超时-人们通常在谈论Lambda时表示超时。但是,您还需要配置其他超时。看一下AWS CLI文档:

https://docs.aws.amazon.com/cli/latest/reference/index.html

这里有--cli-read-timeout--cli-connect-timeout。如果我要创建一个说有5分钟函数执行超时的Lambda函数,并使用RequestResponse(同步)调用类型使用AWS CLI调用它,则发生的时间将超过1分钟(--cli-read-timeout的默认值) ),AWS Lambda将使该执行失败并触发自动重试,最多重试次数。根据您的描述,我相信您正面临这种麻烦。设置所有超时,然后重试。

更多链接可能会有所帮助:

AWS Lambda using Java - setting the configuration connection/socket timeouts

https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/section-client-configuration.html

https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/ClientConfiguration.html#setSocketTimeout-int-