【问题标题】:AWS Lambda throwing ReadTimeoutAWS Lambda 抛出 ReadTimeout
【发布时间】:2021-07-21 15:14:04
【问题描述】:

我需要调用一次 lambda 函数(无需重试)。 该 lambda 最多需要 5/10 分钟才能执行。

我发现了多篇关于超时的帖子,并尝试了每一篇都没有成功

try {
    InvokeRequest invokeRequest = new InvokeRequest()
        .withFunctionName("mylambdaname")
        .withPayload(objectMapper.writeValueAsString(payload));

    //invokeRequest.setSdkRequestTimeout(0);
    //invokeRequest.setSdkClientExecutionTimeout(0);
    //invokeRequest.withSdkRequestTimeout(0);
    //invokeRequest.withSdkClientExecutionTimeout(0);

    AWSLambda awsLambda = AWSLambdaClientBuilder.standard()
        .withCredentials(new EC2ContainerCredentialsProviderWrapper())
        .withRegion(Regions.EU_WEST_1)
        .withClientConfiguration(new ClientConfiguration()
            //.withConnectionTimeout(0)
            //.withRequestTimeout(0)
            //.withClientExecutionTimeout(0)
            //.withSocketTimeout(0)
            .withMaxErrorRetry(0)
        ).build();

    awsLambda.invoke(invokeRequest);
} catch (ServiceException | JsonProcessingException e) {
    LOGGER.error(e.getMessage());
}

设置超时(如 15*60*1000)或无 (0) 仍会在整整一分钟后触发 ReadTimeout。 我还尝试从 AWS 安装 SDK v2,但出现了同样的问题。

尝试过的例子:

PS:如果长任务被缩短,lambda 确实有效,所以这里都是关于超时的

完整的堆栈跟踪

java.net.SocketTimeoutException: 读取超时 在 java.net.SocketInputStream.socketRead0(本机方法) 在 java.net.SocketInputStream.socketRead(SocketInputStream.java:116) 在 java.net.SocketInputStream.read(SocketInputStream.java:171) 在 java.net.SocketInputStream.read(SocketInputStream.java:141) 在 sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:457) 在 sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68) 在 sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1095) 在 sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:72) 在 sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:815) 在 org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137) 在 org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153) 在 org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280) 在 org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138) 在 org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56) 在 org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) 在 org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) 在 org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157) 在 org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) 在 com.amazonaws.http.protocol.SdkHttpRequestExecutor.doReceiveResponse(SdkHttpRequestExecutor.java:82) 在 org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) 在 org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) 在 org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) 在 org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) 在 org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) 在 org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) 在 com.amazonaws.http.apache.client.impl.SdkHttpClient.execute(SdkHttpClient.java:72) 在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258) 在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1074) 在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:745) 在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:719) 在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:701) 在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:669) 在 com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:651) 在 com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:515) 在 com.amazonaws.services.lambda.AWSLambdaClient.doInvoke(AWSLambdaClient.java:2682) 在 com.amazonaws.services.lambda.AWSLambdaClient.invoke(AWSLambdaClient.java:2651) 在 com.amazonaws.services.lambda.AWSLambdaClient.invoke(AWSLambdaClient.java:2640) 在 com.amazonaws.services.lambda.AWSLambdaClient.executeInvoke(AWSLambdaClient.java:1503) 在 com.amazonaws.services.lambda.AWSLambdaClient.invoke(AWSLambdaClient.java:1474)
在 Repository.invokeLambda(Repository.java:60)
在 Service.invoke(Service.java:40)
在 Controller.invoke(Controller.java:37)
在 Controller$$FastClassBySpringCGLIB$$9d602606.invoke()

【问题讨论】:

  • 你有完整的堆栈跟踪吗?
  • @mattfreake 提供了它:)
  • 将 SocketTimeout 设置为 0 不会留下堆栈跟踪,lambda 在整整一分钟(超时)后失败,没有预期的日志,但不会抛出此类异常
  • 你能分享一下 Spring Boot 的确切版本,AWS SDK。我尝试使用 aws-sdk 1.11.1010 和 spring boot 2.4.5 和 spring cloud Hoxton.SR11 运行良好,功能需要 14 分钟的时间。如果你能创建一个 git repo,那就太好了。
  • 同意 - 如果您创建一个 GIT 实例。社区可以帮助您更好地解决问题。我的建议是停止使用 Java V1 并转向 V2。 (使用 V2 是更好的做法)

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


【解决方案1】:

这些方法应该可以解决我看到您已注释掉的技巧:

  • setSDKRequestTimeout(int milliseconds)
  • setSdkClientExecutionTimeout(int milliseconds)

我认为你不应该使用 0。你应该使用 15*60*1000

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

【讨论】:

  • cmets 是我已经尝试过的方法。我知道这些方法应该可以解决问题,但它们都没有。这可能是由于 SB/SC/SDK 版本
  • 另外 0 确实会强制“无超时”,并且应该保持一切正常,直到同步执行结束。 > stackoverflow.com/questions/39615009/… : "(或者干脆 --cli-read-timeout 0 完全禁用超时)"
【解决方案2】:

这对我有用,超时值设置为 15 分钟:

AWSLambdaClientBuilder.standard().withClientConfiguration(new ClientConfiguration().withSocketTimeout(900000)) 

您可以检查 AWS 上的默认 lambda 超时值吗? AWS -> Lambda -> 你的函数 -> 更改超时设置。

【讨论】:

    猜你喜欢
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 2022-01-06
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    相关资源
    最近更新 更多