DynamoDB 导致 Lambda 超时
DynamoDB causing Lambda timeout
我遇到一个问题,即 Lambda 函数偶尔会超时,除了函数超时的通知外,没有任何错误消息。
为了找到问题的根源,我在整个函数的各个点添加了日志记录,并确定一切正常,直到第一个 getItem() 请求从 DynamoDB 读取数据。读取似乎超过 3.00 秒超时。
当然,我检查了我的 DynamoDB table 以查看是否存在任何限制读取或错误。 DynamoDB 的指标显示没有节流或错误,并且读取时间最多保持在两位数毫秒内。
很明显,有些地方出了问题,或者中途掉线了。我该如何解决这个问题或至少抓住它并重试读取?
这是面向网络的读取功能 API,因此响应时间至关重要。因此,增加超时不会解决问题。
dynamodb.getItem({
"TableName": "tablename",
"Key": { "keyname": { "S": "keyvalue" } },
"AttributesToGet": [ "attributeA", "attributeB" ]
}, function(err, data) {
if(err){
context.done(err);
} else {
if("Item" in data){
nextFunction(event, context);
} else {
context.done("Invalid key");
}
}
});
大幅增加超时后,发现最终抛出网络错误:
{
"errorMessage": "write EPROTO",
"errorType": "NetworkingError",
"stackTrace": [
"Object.exports._errnoException (util.js:870:11)",
"exports._exceptionWithHostPort (util.js:893:20)",
"WriteWrap.afterWrite (net.js:763:14)"
]
}
根据 this thread,此问题似乎是由 Node.js 和 OpenSSL 之间的问题引起的。听起来这个问题影响 Node.js 4.x 及以上但不影响 0.10。这意味着您可以通过将 Lambda 运行时降级到 Node.js 0.10 或在使用 aws-sdk 时添加以下代码来解决问题:
new AWS.DynamoDB({
httpOptions: {
agent: new https.Agent({
rejectUnauthorized: true,
secureProtocol: "TLSv1_method",
ciphers: "ALL"
})
}
});
运行 在 "put" 将数据从 lambda 传输到 DynamoDB 时出现随机 lambda 超时问题。 Lambda 驻留在 VPC 中(根据组织策略)。
问题:一些(随机的)lambda 容器在放置数据时会持续失败并超时(设置为 30 秒),而其他容器在几毫秒内完成放置数据。
根本原因:配置了两个子网(按照 AWS 的建议)。一个是私有子网,另一个是 public 子网。当一个新的 lambda 容器被剥离时,它会随机 select 其中一个子网。如果它选择 public 子网,它会一直失败。如果它选择私有子网,它会在几毫秒内完成。
解决方案:删除 public 子网,而是配置两个私有子网。
如果您在 VPC 中启动 Lambda,请尝试在私有子网而不是 Public 子网中启动。
我遇到了同样的问题,在私有子网中启动 Lambda 对我有用。
不要忘记将此添加到私有子网中 Lambda 运行 的 SG:
到您的 DynamoDB VPC 端点的前缀列表 ID 的出站 HTTPS 连接
我花了几个小时才意识到这一点。 Lambda 使用 https 联系您 VPC 中的 DynamoDB 网关。
我遇到一个问题,即 Lambda 函数偶尔会超时,除了函数超时的通知外,没有任何错误消息。
为了找到问题的根源,我在整个函数的各个点添加了日志记录,并确定一切正常,直到第一个 getItem() 请求从 DynamoDB 读取数据。读取似乎超过 3.00 秒超时。
当然,我检查了我的 DynamoDB table 以查看是否存在任何限制读取或错误。 DynamoDB 的指标显示没有节流或错误,并且读取时间最多保持在两位数毫秒内。
很明显,有些地方出了问题,或者中途掉线了。我该如何解决这个问题或至少抓住它并重试读取?
这是面向网络的读取功能 API,因此响应时间至关重要。因此,增加超时不会解决问题。
dynamodb.getItem({
"TableName": "tablename",
"Key": { "keyname": { "S": "keyvalue" } },
"AttributesToGet": [ "attributeA", "attributeB" ]
}, function(err, data) {
if(err){
context.done(err);
} else {
if("Item" in data){
nextFunction(event, context);
} else {
context.done("Invalid key");
}
}
});
大幅增加超时后,发现最终抛出网络错误:
{
"errorMessage": "write EPROTO",
"errorType": "NetworkingError",
"stackTrace": [
"Object.exports._errnoException (util.js:870:11)",
"exports._exceptionWithHostPort (util.js:893:20)",
"WriteWrap.afterWrite (net.js:763:14)"
]
}
根据 this thread,此问题似乎是由 Node.js 和 OpenSSL 之间的问题引起的。听起来这个问题影响 Node.js 4.x 及以上但不影响 0.10。这意味着您可以通过将 Lambda 运行时降级到 Node.js 0.10 或在使用 aws-sdk 时添加以下代码来解决问题:
new AWS.DynamoDB({
httpOptions: {
agent: new https.Agent({
rejectUnauthorized: true,
secureProtocol: "TLSv1_method",
ciphers: "ALL"
})
}
});
运行 在 "put" 将数据从 lambda 传输到 DynamoDB 时出现随机 lambda 超时问题。 Lambda 驻留在 VPC 中(根据组织策略)。
问题:一些(随机的)lambda 容器在放置数据时会持续失败并超时(设置为 30 秒),而其他容器在几毫秒内完成放置数据。
根本原因:配置了两个子网(按照 AWS 的建议)。一个是私有子网,另一个是 public 子网。当一个新的 lambda 容器被剥离时,它会随机 select 其中一个子网。如果它选择 public 子网,它会一直失败。如果它选择私有子网,它会在几毫秒内完成。
解决方案:删除 public 子网,而是配置两个私有子网。
如果您在 VPC 中启动 Lambda,请尝试在私有子网而不是 Public 子网中启动。 我遇到了同样的问题,在私有子网中启动 Lambda 对我有用。
不要忘记将此添加到私有子网中 Lambda 运行 的 SG: 到您的 DynamoDB VPC 端点的前缀列表 ID 的出站 HTTPS 连接
我花了几个小时才意识到这一点。 Lambda 使用 https 联系您 VPC 中的 DynamoDB 网关。