为什么 aws lambda 调用客户端错误地返回 ClientExecutionTimeoutException?
Why is aws lambda invocation client incorrectly returning ClientExecutionTimeoutException?
我们似乎确定性地遇到了这个问题,但不确定我们在哪里配置错误。对于小于 ~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 分钟的超时配置?
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 上下文。
您的函数可能不会 return 成功但 return 失败,因为您没有在上下文成功的情况下完成该函数。
请在完成lamba后检查是否这样做。
谢谢。
我接受了 Ezequiel 的回答,因为它在技术上是一个网络/OS 问题,但这里有一个更详细的结果:
我们必须确保所有相关客户端都配置为保持活动的 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
我们似乎确定性地遇到了这个问题,但不确定我们在哪里配置错误。对于小于 ~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 分钟的超时配置?
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 上下文。 您的函数可能不会 return 成功但 return 失败,因为您没有在上下文成功的情况下完成该函数。 请在完成lamba后检查是否这样做。
谢谢。
我接受了 Ezequiel 的回答,因为它在技术上是一个网络/OS 问题,但这里有一个更详细的结果:
我们必须确保所有相关客户端都配置为保持活动的 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