为啥 aws lambda 调用客户端错误地返回 ClientExecutionTimeoutException?

Posted

技术标签:

【中文标题】为啥 aws lambda 调用客户端错误地返回 ClientExecutionTimeoutException?【英文标题】:Why is aws lambda invocation client incorrectly returning ClientExecutionTimeoutException?为什么 aws lambda 调用客户端错误地返回 ClientExecutionTimeoutException? 【发布时间】:2020-04-06 00:37:18 【问题描述】:

我们似乎确定性地遇到了这个问题,并且不确定我们在哪里配置错误。对于运行不到约 5 分钟的 lambda,我们的调用在 lambda 完成后约 0.5 秒成功结束。然而,对于任何运行时间更长的东西,我们可以在 lambda 日志中看到 lambda 完成,但我们的客户端调用在 15 分钟后抛出 ClientExecutionTimeoutException

在遇到其他(否则成功的)lambda 的问题后,我们在 Node 上创建了一个带有睡眠功能的基本测试 lambda,并且能够确定性地重现该问题:

function sleep(s) 
  return new Promise(resolve => setTimeout(resolve, s * 1000));

const sleepMinutes = 60 * 5;
exports.handler = async (event) => 
    console.log(`received lambda invocation, sleeping $sleepMinutes`);
    const response = 
        statusCode: 200,
        body: JSON.stringify(`finished running, slept for $sleepMinutes minutes`),
    ;
    await sleep(sleepMinutes);
    console.log('finished sleeping');
    return response;
;

我们的 lambda 调用客户端正在使用这些客户端配置:

clientConfig.setRetryPolicy(PredefinedRetryPolicies.NO_RETRY_POLICY);
clientConfig.setMaxErrorRetry(0);
clientConfig.setSocketTimeout(15 * 60 * 1000);
clientConfig.setRequestTimeout(15 * 60 * 1000);
clientConfig.setClientExecutionTimeout(15 * 60 * 1000);

是否缺少约 5 分钟的超时配置?

【问题讨论】:

你能在日志中看到“完成睡眠”吗? 是的。查看 lambda 日志,一切似乎都结束了 在进一步的测试中,我能够通过从 CLI 调用 lambdas 来重现该问题。在运行 8 分钟并成功的 lambda 上,该命令在大约 6 分钟内失败。似乎有一个网络配置结束了这个 tcp 连接? 这是来自 /etc/os-release: NAME="Amazon Linux AMI" VERSION="2017.03" ID="amzn" ID_LIKE="rhel fedora" VERSION_ID="2017.03" PRETTY_NAME="Amazon Linux AMI 2017.03" ANSI_COLOR="0;33" CPE_NAME="cpe:/o:amazon:linux:2017.03:ga" HOME_URL="aws.amazon.com/amazon-linux-ami" 【参考方案1】:

aws-sdk-java 中的 Javadocs 说:

 For functions with a long timeout, your client might be disconnected during synchronous invocation while it waits for a response. Configure your HTTP client, SDK, firewall, proxy, or operating system to allow for long connections with timeout or keep-alive settings.

另一方面,之前 AWS Lambda 限制为 5 分钟,后来这个限制增加到 15 分钟。

我会检查:

    客户端sdk版本是最新的 您的网络没有关闭连接 通过AWSLambdaAsyncClient.invokeAsync() 移至异步调用以进行长时间运行的调用。

【讨论】:

澄清一下,问题不在于我的客户在 lambda 完成之前返回。问题是对于运行时间超过 5 分钟的 lambda,lambda 完成,但我的客户将继续等待响应,直到 15 分钟超时发生 我们使用的是 java sdk 版本 1.11.616,由于其他原因异步调用不适合我们的用例【参考方案2】:

我接受了 Ezequiel 的回答,因为它在技术上是网络/操作系统问题,但这里有一个更详细的结果:

我们必须确保所有相关客户端都配置为保持 tcp 连接处于活动状态。然后,我们必须将这些属性添加到位于私有子网中的 EC2 上的 /etc/sysctl.conf 文件中,因为 NAT 网关设置为 kill idle connections beyond 350s:

net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 100
net.ipv4.tcp_keepalive_probes = 6

【讨论】:

【参考方案3】:

我遇到过这样的错误。 问题在于 lambda 上下文。 您的函数可能不会返回成功但返回失败,因为您没有在上下文成功的情况下完成函数。 请在完成lamba时检查您是否已这样做。

谢谢。

【讨论】:

以上是关于为啥 aws lambda 调用客户端错误地返回 ClientExecutionTimeoutException?的主要内容,如果未能解决你的问题,请参考以下文章

为啥要缓存对 MySQL RDS 的 AWS Lambda python 调用?

为啥我的 AWS Lambda 脚本返回“实例”而不是实例 ID?

为啥 AWS Lambda CFN S3 响应在删除事件时返回 403?

AWS Lambda NodeJS导入返回空模块,但仅在AWS中

使用代理通过 AWS API Gateway 的 Lambda 错误

AWS Lambda,API Gateway 返回 Malformed Lambda 代理响应,502 错误