AWS lambda 函数在超时错误后停止工作

Posted

技术标签:

【中文标题】AWS lambda 函数在超时错误后停止工作【英文标题】:AWS lambda function stops working after timed out error 【发布时间】:2016-09-10 23:57:06 【问题描述】:

我有一个简单的 lambda 函数,它异步进行 API 调用,然后返回数据。 99% 的时间这都很好。当 API 花费的时间超过 lambda 配置的超时时间时,它会按预期给出错误。现在的问题是,当我对 lambda 函数进行任何后续调用时,它会永久地给我超时错误。

 "errorMessage": "2016-05-14T22:52:07.247Z session Task timed out after 3.00 seconds"

为了测试是否是这种情况,我将 lambda 超时设置为 3 秒,并有办法在 lambda 中触发这两个函数。

Javascript

function now()  
    return response.tell('success'); 


function wait() 
    setTimeout(function()  return response.tell('success'); , 4000);

当我调用now 函数时没有问题。当我调用 wait 函数时,我收到超时错误,然后对 now 的任何后续调用都会给我同样的错误。

这是预期的行为吗?我认为对 lambda 函数的任何后续调用都应该有效。我知道我总是可以增加配置超时,但宁愿不要。

【问题讨论】:

你捕获日志吗? cloudwatch 中的任何内容 这是我在上面一遍又一遍地发布的错误消息。 我一直在玩同样的问题。在进行任何库导入之前,我将 console.log 作为索引处理程序文件的第一行。该console.log 命中随后的超时,但之后没有日志!它正在停止进口。我不知道 AWS 在做什么,但由于某种原因它无法加载外部库失败(或者需要很长时间)。 similar question 我经常看到人们询问 Node.js,但这在 Python(至少 3.6)中也是一个问题。 @duhseekoh 经历过同样的事情:从第一行打印什么也不返回。 【参考方案1】:

我认为问题在于我们在 AWS RDS 入站/出站中提到的 IP 地址。

如果您现在正在测试并且您的 node.js 正在本地 ide 上而不是 AWS 上运行,那么您必须执行以下操作:

    转到 AWS RDS。

    点击数据库实例。

    单击该数据库实例的名称。 转到下面的“连接”部分,您可以在其中找到安全组角色。 安全组的类型为入站、出站。 一一点击。它将打开一个新窗口。 同样会有两个选项卡用于入站和出站。 一个接一个地点击。 点击“编辑”。 选择“任何地方”而不是“自定义”。附言对入站/出站重复此操作。

全部设置。

【讨论】:

【参考方案2】:

我只需要增加超时时间,错误就会消退。 我把它增加到5秒。 这对我来说没问题,因为我不会在生产中使用这个 Lambda。

【讨论】:

【参考方案3】:

我也遇到过同样的问题,其实很多情况下 Lambda 都会无响应,例如:

    解析无效的json:

    exports.handler = function(event, context, callback)
    
        var nonValidJson = "Not even Json";
        var jsonParse = JSON.parse(nonValidJson);
    

    访问未定义变量的属性:

    exports.handler = function(event, context, callback)
    
        var emptyObject = ;
        var value = emptyObject.Item.Key;
    

    访问 RDS 后未关闭 mysql 连接会导致 Lambda 超时,然后变得无响应。

当我说无响应时,它实际上甚至没有加载,即没有打印处理程序中的第一个打印,并且 Lambda 只是在每次运行时退出超时:

exports.handler = function(event, context, callback)

    console.log("Hello there");

这是一个错误,AWS 团队已经知道了将近一年:https://forums.aws.amazon.com/thread.jspa?threadID=238434&tstart=0

不幸的是它仍然没有修复,经过一些测试后发现实际上 Lambda 尝试重新启动(重新加载容器?),只是时间不够。如果您将超时设置为 10 秒,则在大约 4 秒的执行时间后,Lambda 开始工作,然后在下一次运行中正常运行。我也尝试过设置:

context.callbackWaitsForEmptyEventLoop = false;

并将所有“需要”块放入处理程序中,没有任何效果。防止 Lambda 死机的唯一方法是设置更大的超时时间,10 秒应该足以作为解决此错误的解决方法。

【讨论】:

当我将 require 语句放在 exports.handler 的正文中而不是在脚本的顶层时,我遇到了三秒超时错误。【参考方案4】:

在 Amazon 控制台 AWS 配置中,您必须将默认超时时间从 3 秒更改为更长(最多 5 分钟)

【讨论】:

这不是一个好方法,因为如果您将 lambda 提高到 300 秒,也可能会发生超时。【参考方案5】:

你应该看看你的函数句柄是如何与特定的 context.callbackWaitsForEmptyEventLoop

如果该布尔类型为false,则永远不会触发 setTimeout,因为您之前可能已经回答/处理了 lambda 调用。 但是如果callbackWaitsForEmptyEventLoop 的值是true - 那么你的代码就会做你想要的。

另外 - 通过回调直接处理所有事情可能更容易,无需“手写”超时、更改配置超时等等......

例如

function doneFactory(cb)  // closure factory returning a callback function which knows about res (response)
  return function(err, res) 
    if (err) 
      return cb(JSON.stringify(err));
    
    return cb(null, res);
  ;


// you're going to call this Lambda function from your code
exports.handle = function(event, context, handleCallback) 

  // allows for using callbacks as finish/error-handlers
  context.callbackWaitsForEmptyEventLoop = false;

  doSomeAsyncWork(event, context, doneFactory(handleCallback));
;

【讨论】:

你先生是生活品味!【参考方案6】:

如果您在函数配置中定义了 3 秒,此超时将覆盖代码中的时间,因此请确保从您的 lambda 函数配置中增加超时并再次尝试 wait(),它应该可以工作!

【讨论】:

我不是在问为什么我的函数超时。我在问为什么所有后续函数都会超时,即使它们不应该。 我无法告诉您底层 node.js 解释器如何在 Lambda 中工作,但如果您按秒付费,优化解释器以执行等待或休眠是没有意义的,这可能是原因。但这只是一个猜测。。问问 AWS 支持的人,也许他们会给你更多的见解

以上是关于AWS lambda 函数在超时错误后停止工作的主要内容,如果未能解决你的问题,请参考以下文章

在将 aws lambda 与 redis 连接时,任务在 23.02 秒后超时错误

适用于 postgreSQL 的 AWS Lambda 函数 NodeJs - 超时错误

如何暂停/恢复aws lambda函数

是啥导致 AWS Lambda 上的 Mongodb 超时错误?

如何暂停/恢复 aws lambda 函数

使用 Lambda 函数覆盖 AWS Auto Scaling 策略