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

jjb*_*kir 37 amazon-web-services node.js aws-lambda

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

 "errorMessage": "2016-05-14T22:52:07.247Z {session} Task timed out after 3.00 seconds"
Run Code Online (Sandbox Code Playgroud)

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

使用Javascript

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

function wait() {
    setTimeout(function() { return response.tell('success'); }, 4000);
}
Run Code Online (Sandbox Code Playgroud)

当我调用该now函数时没有问题.当我调用该wait函数时,我得到超时错误,然后任何后续调用now给我相同的错误.

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

小智 16

您应该查看函数句柄如何与特定的一起使用 context.callbackWaitsForEmptyEventLoop

如果是boolean类型false,则不会触发setTimeout,因为您可能先前已经回答/处理了lambda调用.但是,如果值callbackWaitsForEmptyEventLooptrue-你的代码会做你在找什么.

此外 - 通过回调直接处理所有内容可能更容易,无需"手写"超时,更改配置超时等等......

例如

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));
};
Run Code Online (Sandbox Code Playgroud)

  • 你先生是一种生活品味! (2认同)

小智 9

好吧,如果你在你的函数配置中定义了3秒,这个超时将覆盖你的代码内部的时间,所以确保增加lambda函数配置的超时并再次尝试wait(),它应该工作!


小智 6

我遇到了同样的问题,实际上有很多情况下 Lambda 变得无响应,例如:

  1. 解析无效的 json:

    exports.handler = function(event, context, callback)
    {
        var nonValidJson = "Not even Json";
        var jsonParse = JSON.parse(nonValidJson);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 访问未定义变量的属性:

    exports.handler = function(event, context, callback)
    {
        var emptyObject = {};
        var value = emptyObject.Item.Key;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 访问 RDS 后不关闭 mySql 连接会导致 Lambda 超时,然后变得无响应。

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

exports.handler = function(event, context, callback)
{
    console.log("Hello there");
Run Code Online (Sandbox Code Playgroud)

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

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

context.callbackWaitsForEmptyEventLoop = false;
Run Code Online (Sandbox Code Playgroud)

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