简体   繁体   English

AWS Lambda - Mongoose 连接超时

[英]AWS Lambda - Mongoose connection timeout

I'm trying to reuse the mongodb connection for AWS Lambdas, this is my connection function:我正在尝试为 AWS Lambdas 重用 mongodb 连接,这是我的连接功能:

const openMongodbConnection = ({ config }) => (
  process.mongoConnection ? Promise.resolve() : mongoose.connect(config.MONGO_URL, {
    bufferCommands: false,
    bufferMaxEntries: 0,
    keepAlive: true,
  })

  .then((connection) => {
    process.mongoConnection = connection;
    return Promise.resolve();
  }, err => (
    Promise.reject({
      statusCode: 500,
      errorCode: [{
        code: 'DatabaseError',
        description: `unable to connect to mongo db: ${err} ${JSON.stringify(config)}`,
      }],
    })
  ))
);

Database is within an AWS VPC and doesn't have external access.数据库位于 AWS VPC 内,没有外部访问权限。 Cold start works perfectly, but sometimes I get a timeout error like this:冷启动工作完美,但有时我会收到这样的超时错误:

2018-10-03T18:36:06.984Z    7ab97df7-c739-11e8-89bf-87260b172585    MongoNetworkError: connection 2 to some.ip.from.server:27017 timed out
at Socket.<anonymous> (/var/task/node_modules/mongodb-core/lib/connection/connection.js:258:7)
at Socket.g (events.js:292:16)
at emitNone (events.js:86:13)
at Socket.emit (events.js:185:7)
at Socket._onTimeout (net.js:338:8)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)

I also have context.callbackWaitsForEmptyEventLoop = false;我也有context.callbackWaitsForEmptyEventLoop = false; right on the start of the function.就在函数的开头。

This error is completely random, sometimes work and sometimes doesn't, I'm thinking on opening and closing the connection everytime a new request comes up, but I know this will reduce the performance of lambdas and also will increase the I/O operations from the mongodb server.这个错误是完全随机的,有时有效,有时无效,我正在考虑每次出现新请求时打开和关闭连接,但我知道这会降低 lambdas 的性能,也会增加 I/O 操作来自 mongodb 服务器。

Help will be greatly appreciated.帮助将不胜感激。

Well, I came here looking for an answer to this myself.. anyway, the ONLY answer we have found so far is to open and close the DB connection each time the lambda is invoked. 好吧,我来这里寻找自己的答案..无论如何,我们到目前为止找到的唯一答案是每次调用lambda时打开和关闭数据库连接。

Apparently, when the lambda isn't working, AWS suspends the process which means the socket looks dead to the mongodb server, so it drops the connection because it thinks it's a dead client. 显然,当lambda不工作时,AWS会暂停进程,这意味着套接字看起来已经死了mongodb服务器,因此它会丢弃连接,因为它认为它是一个死客户端。 Thus trying to keep the socket around between lambda invokes leads to this timeout quite often. 因此,尝试在lambda调用之间保持套接字会导致此超时。

The problem is when the lambda function is trigger from AWS Fargate. 问题是当lambda函数从AWS Fargate触发时。

When AWS uses IAMRole:PassRole it brakes the VPC/Subnet configuration, thus making the lambda function not able to connect to the mongo database. 当AWS使用IAMRole:PassRole时,它会制动VPC / Subnet配置,从而使lambda函数无法连接到mongo数据库。

We have experienced the same issue.我们也遇到过同样的问题。 it turns out our problem was mainly with making the connection outside the handler function .connection was being opened without the handler function being actually called and only by requiring lambda.js file.事实证明,我们的问题主要是在处理程序函数之外建立连接 .connection 在没有实际调用处理程序函数的情况下被打开,并且只需要lambda.js文件。

The issue has vanished when we moved the connection code inside handler function:当我们将连接代码移到处理程序函数中时,问题就消失了:

// lambda.js

// DO NOT open mongodb connection here


exports.handler = async (event, context) => {
    // open the mongo connection here
    // openMongodbConnection()
}

I am not exactly sure how could this cause an issue but it is probably has something to do with the sequence to which subnet configuration will be applied.我不确定这会如何导致问题,但这可能与将应用子网配置的顺序有关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM