来自AWS Lambda的MongoDB连接

Bee*_*ees 52 mongodb amazon-web-services node.js aws-lambda

我正在寻找使用连接到MongoDB数据库的AWS Lambda/API Gateway创建RESTful API.我已经读过与MongoDB的连接相对昂贵,因此最好的做法是在建立连接后保留连接以便重用,而不是为每个新查询建立新连接.

这对于普通应用程序来说非常简单,因为您可以在启动期间建立连接并在应用程序生命周期内重用它.但是,由于Lambda被设计为无国籍,因此保持这种联系似乎不太直接.

因此,我想知道什么是解决此数据库连接问题的最佳方法?我是否每次调用Lambda函数时都强制建立新连接,或者是否有办法池/缓存这些连接以获得更有效的查询?

谢谢.

tul*_*ler 13

AWS Lambda函数应定义为无状态函数,因此它们不能像连接池那样保持状态.

AWS论坛帖子中也提出了此问题.在2015年10月5日AWS工程师肖恩贴,你应该打开并在每次请求紧密结合,通过创建代码初始化一个游泳池,处理器块之外.但两天后,同一位工程师发布说你不应该这样做.

问题是您无法控制Lambda的运行时环境.我们知道这些环境(或容器)可以重复使用,正如Tim Wagner所描述的博客文章所述.但缺乏控制可能会导致您耗尽所有资源,例如在数据库中达到连接限制.但这取决于你.

您可以使用RESTHeart通过HTTP访问数据库,而不是从lambda函数连接到MongoDB .MongoDB的连接池由RESTHeart维护.请记住,在性能方面,您将在每个请求上打开与RESTHeart的新HTTP连接,而不是像在传统应用程序中那样使用HTTP连接池.

  • 我可以抛出一分...... MongoDB Atlas已经有了HTTP API,所以你可以使用它.和RESTHeart非常相似,我最近和Lambda一起使用它,非常好的东西. (7认同)

Tyl*_*ock 7

您应该假设 lambda 是无状态的,但实际情况是,大多数时候虚拟机只是冻结并保持某种状态。对于亚马逊来说,为每个请求启动一个新流程的效率很低,因此他们经常重复使用相同的流程,您可以利用这一点来避免连接抖动。

为了避免每个请求都进行连接(在重复使用 lambda 进程的情况下):

  1. 编写处理程序,假设该进程被重用,这样您就可以连接到数据库并让lambda 重用连接池(db从 中返回的承诺MongoClient.connect)。

  2. 为了使 lambda 不会挂起等待您关闭数据库连接,db.close()在为请求提供服务后告诉它不要等待空事件循环。

例子:

var db = MongoClient.connect(MongoURI);

module.exports.targetingSpec = (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false;
  db.then((db) => {
    // use db
  });
};
Run Code Online (Sandbox Code Playgroud)

从有关的文档context.callbackWaitsForEmptyEventLoop

callbackWaitsForEmptyEventLoop 默认值为true。此属性仅用于修改回调的默认行为。默认情况下,回调将等到 Node.js 运行时事件循环为空,然后再冻结进程并将结果返回给调用者。您可以将此属性设置为 false,以请求 AWS Lambda 在调用回调后立即冻结进程,即使事件循环中存在事件也是如此。AWS Lambda 将冻结进程、Node.js 事件循环中的任何状态数据和事件(下次调用 Lambda 函数时并且如果 AWS Lambda 选择使用冻结进程,则处理事件循环中的任何剩余事件)。有关回调的更多信息,请参阅使用回调参数。


小智 5

Restheart是一个基于REST的服务器,与MongoDB一起运行.当您需要编写自定义处理程序时,它会将Mongo中的大多数CRUD操作映射到GET,POST等,具有可扩展支持的请求(例如,专门的geoNear,geoSearch查询)