为啥 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中