【问题标题】:DynamoDB causing Lambda timeoutDynamoDB 导致 Lambda 超时
【发布时间】:2016-09-24 19:28:48
【问题描述】:

我遇到了一个问题,即 Lambda 函数偶尔会超时,除了函数超时通知之外没有任何错误消息。

为了找到问题的根源,我在整个函数的各个点添加了日志记录,并确定一切正常,直到第一个 getItem() 请求从 DynamoDB 读取数据。读取时间似乎超过了 3.00 秒的超时时间。

当然,我检查了我的 DynamoDB 表以查看是否存在任何限制读取或错误。 DynamoDB 的指标显示没有限制或错误,读取时间最多保持在两位数毫秒内。

很明显,有些地方出了问题或在途中被丢弃了。我该如何解决这个问题,或者至少抓住它并重试读取?

这是一个面向读取的 Web 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");
    }
  }
});

【问题讨论】:

    标签: node.js amazon-dynamodb aws-sdk aws-lambda


    【解决方案1】:

    显着增加超时后,发现最终抛出网络错误:

    {
        "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"
        })
      }
    });
    

    【讨论】:

    • 您尝试过使用 TLS v1 吗?
    • 这里的棘手之处在于,为了能够调试这些问题,您需要让 DynamoDB 调用失败。如果在 Lambda 中使用,请确保调用在 Lambda(或 API 网关)超时之前失败。我们在这里详细描述了它 - seed.run/blog/…
    • 谢谢,增加超时对我来说至关重要。
    【解决方案2】:

    在将数据从 lambda“放入”到 DynamoDB 时遇到随机 lambda 超时问题。 Lambda 驻留在 VPC 中(根据组织策略)。

    问题:一些(随机)lambda 容器在放入数据和超时(设置为 30 秒)时会始终失败,而其他容器在几毫秒内完成数据放入。

    根本原因:配置了两个子网(如 AWS 建议的那样)。一个是私有子网,另一个是公共子网。当一个新的 lambda 容器被分离出来时,它会随机选择一个子网。如果它选择公共子网,它将始终失败。如果它选择私有子网,它将在几毫秒内完成。

    解决方案:删除公共子网,而是配置两个私有子网。

    【讨论】:

    • 是什么原因导致它在公共子网中失败而在私有子网中成功? lambda函数必须在私有子网中的原因是什么?
    • Lambda 函数位于 VPC 中,因为它访问 Aurora RDS。有关如何从 VPC 中的 lambda 访问 Internet(本例中为 DynamoDB 端点)的更多信息,请参阅aws.amazon.com/premiumsupport/knowledge-center/…
    【解决方案3】:

    如果您在 VPC 中启动 Lambda,请尝试在私有子网而不是公共子网中启动。 我遇到了同样的问题,在私有子网中启动 Lambda 对我有用。

    【讨论】:

    • 我遇到了同样的问题,因为我没有在私有子网上设置 NAT 网关,Lambda 无法调用 dynamo API。
    【解决方案4】:

    不要忘记将此添加到在私有子网中运行的 Lambda 的 SG: 出站 HTTPS 连接到您的 DynamoDB VPC 端点的前缀列表 ID

    这花了我几个小时才意识到。 Lambda 使用 https 联系您 VPC 中的 DynamoDB 网关。

    【讨论】:

    • 如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review
    猜你喜欢
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 2019-08-01
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多