为什么我的AWS Lambda函数总是超时?

8
我有一个在 node.js 8.10 上运行的 AWS Lambda 函数。该函数使用 ioredis 库连接到 Redis 服务器,获取一个键上的值,然后返回该值。我可以在日志中看到连接成功,并且成功检索到了该值。然而,响应从未返回,如果查看日志,可以看到 lambda 总是超时。
为什么会出现这种情况?是否有某种原因导致 Lambda 继续运行,而不是从 Redis 返回值?
这是我的 Lambda 函数代码:
const Redis = require('ioredis');
const redis = new Redis(6379, 'http://redis.example.com');

exports.handler = async (event, context) => {
  const value = await redis.get('mykey');
  console.log('value', value);  // this shows up in Cloudwatch logs
  return value;
};

1
你的回应需要以特定格式呈现吗?return { statusCode: 200, headers: { "Content-Type": "application/json" }, body: value }; - Get Off My Lawn
1
如果我删除所有的Redis相关内容,只返回一个字符串,比如 'foo',那么它就可以工作了。 - geresader
2个回答

11

简短回答:只需设置 event.callbackWaitsForEmptyEventLoop = false

exports.handler = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false;
  ...
};

这有什么关系?

AWS Lambda中NodeJS运行时的默认行为是在执行lambda并返回一个值之前等待javascript事件循环为空。您可以在此处阅读有关AWS Lambda和node.js事件循环的工作原理的更多信息

因此,您的lambda函数目前正在发生的是与Redis的连接使事件循环保持打开状态,从而阻止您的函数成功结束执行。


7

或者你可以关闭 Redis 连接。


谢谢,这对我有用!在调用set之后,我在回调函数中关闭了Redis连接。奇怪的是,我在另一个Lambda中几乎有相同的实现,但那个Lambda没有超时而不关闭它。 - chris

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