AWS Lambda函数超时

3
在我的本地mocha测试中,以下处理程序函数运行得非常好。然而,当我上传到AWS(使用Serverless框架)时,它会超时(除非您不提供uid参数,在这种情况下它会立即正确地响应)。
特别奇怪的是,在不到3秒的时间内(超时设置为5秒),作业就完成了,甚至输出了“事后”日志消息,但它还是在调用回调函数,而且没有完成Lambda函数。
以下是cloudwatch日志:

![enter image description here]1

以下是handler函数:
export const handler = (event: IRequestInput, context: IContext, cb: IGatewayCallback) => {
  console.log('EVENT:\n', JSON.stringify(event, null, 2));
  const uid = _.get(event, 'queryStringParameters.uid', undefined);
  if(!uid) {
    cb(null, {
      statusCode: 412,
      body: 'no User ID was provided by frontend'
    });
    return;
  }

  oauth.getRequestToken()
    .then(token => {
      console.log('Token is:\n', JSON.stringify(token, null, 2));
      console.log('User ID: ', uid);
      token.uid = uid;
      return Promise.resolve(token);
    })
    .then((token) => {
      console.log('URL: ', token.url);
      cb(null, {
        statusCode: 200,
        body: token.url
      });
      console.log('post-facto');
    })
    .catch((err: PromiseError) => {
      console.log('Problem in getting promise token: ', err);
      cb(err.message);
    });

};
2个回答

10

请将以下代码添加为您的处理函数的第一行:

context.callbackWaitsForEmptyEventLoop = false

哇,太棒了。需要立刻去拿杯咖啡,但还不知道为什么它起作用了。我会研究一下,但如果你有时间,能否解释一下是什么导致了这个结果? - ken
@ken 实际上,Node 会在退出其进程之前等待一个空的事件循环。因此,如果你有一个简单地执行 (function recurse () { setInterval(recurse, 1) })() 的 js 文件,然后使用 node 运行它,该进程将永远不会退出,除非你手动杀死它。除非你添加我回答中的那一行,否则回调 Lambda 将遵守这一点。在这种情况下,Lambda 实际上只会在你调用回调之后调用 process.exit() - idbehold
3
@ken,这也意味着你代码中的某些部分导致事件循环无法排空。数据库连接是典型原因之一,因为它们将会打开一个套接字,而只要套接字仍然打开,Node 就不会认为事件循环为空。 - idbehold
啊哈。数据库连接有很多意义。谢谢。 - ken
你很棒 @idbehold - prashant

0

我猜你正在使用“Node.js Runtime 0.10”与lambda。

所以你应该添加

context.done(null, 'Terminate Lambda');

终止执行。

根据AWS Lambda文档,它提到:

回调仅在Node.js运行时v4.3中受支持。如果您使用早期运行时v0.10.42,则需要使用上下文方法(done、succeed和fail)来正确终止Lambda函数。

请参考此link以获取上述信息。


我正在使用v4.3运行时。 - ken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接