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 网关。