【问题标题】:Aws lambda with mongoDb connection带有 mongoDb 连接的 Aws lambda
【发布时间】:2020-02-27 20:27:48
【问题描述】:

大家好,我需要一个简单问题的答案。我正在将 Aws lambda 与无服务器框架一起使用,并且我在 aws lambda 中使用 mongoDb 连接。我在处理程序函数中使用了连接代码,并且我使用了连接池。

现在,当我使用 sls deploy 在 AWS 上部署我的应用程序时,在我第一次调用我的 lambda 时部署后,连接只建立一次,之后在其他 lambda API 调用上它正在重用我的连接而不是创建新连接。所以这件事很好。

现在,在此过程之后,我正在运行一个与我的 AWS 应用程序无关的脚本来测试我的并发 lambda 请求。我在脚本中的 for 循环中使用 request npm 模块调用了我的相同 lambda API,在这种情况下,我一直在循环终止之前创建新的连接,而不是使用第一次调用生成的现有连接。有人可以告诉我为什么会发生这种情况以及这背后的原因是什么?为什么我已经在第一次 lambda 调用时创建了连接,但当此脚本运行时我的连接再次创建。

当我从邮递员调用相同的 api 时,它会在第一次 lambda 调用后恢复我的连接,但是当我运行此脚本并从内部脚本中,我使用命令“node app.js”调用此 API(使用请求 NPM 模块)然后一直到循环终止它都会创建新的连接。

请帮帮我。

 'use strict'

 const bodyParser = require('body-parser')
 const express = require('express')
 const serverless = require('serverless-http')
 const cors = require('cors');
 const mongoConnection = require('./connection/mongoDb');
 const app = express()

app.use(cors())
app.use(bodyParser.json())

const handler = serverless(app);
let cachedDb = null;

module.exports.handler = async (event, context) => {
context.callbackWaitsForEmptyEventLoop = false;
if (cachedDb == null) {
let Database = await mongoConnection();
console.log("DB", Database);
cachedDb = Database
}

const baseRouter = require('./routes/index');
app.use('/api', baseRouter);

const result = await handler(event, context);
return result;
};

【问题讨论】:

  • 你会分享你的任何代码 sn-ps 吗?
  • 我已经使用来自官方网站的 mongodb 连接的 aws lambda 的普通代码,代码没有问题。这个概念是如何工作的,我不明白。
  • 如果没有您部署到 lambda 的实际代码,这真的很难说,如果您发布处理程序代码,我可以看看。但如果我不得不猜测,它与您如何确定连接变量和容器重用的范围有关(请参阅aws.amazon.com/blogs/compute/container-reuse-in-lambda)。
  • 我已添加代码请查看此@LucHendriks

标签: node.js mongodb aws-lambda api-gateway


【解决方案1】:

这是一个显示连接参数的 node.js 示例。也许这会有所帮助?

const express = require("express");
const bodyParser= require("body-parser")
const app = express();
const MongoClient = require("mongodb").MongoClient


MongoClient.connect("mongodb://myusername:mypassword@localhost:27017", (err, client) => {
  if (err) return console.log(err)

  var db = client.db("mydatabase")

  db.collection("mycollection").countDocuments(getCountCallback);

  app.listen(3000, () => {
    console.log("listening on 3000")
  })  
})


function getCountCallback(err, data) {
  console.log(data);
}

app.use(bodyParser.urlencoded({extended: true}))

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html")
})

app.post("/quotes", (req, res) => {
  console.log(req.body)
})

您的示例代码没有显示您的数据库服务器的任何主机名,也没有指定要使用的端口。请比较您的代码并与我的示例进行对比。

【讨论】:

  • 我不想要代码,我想详细了解 lambda 容器的工作原理。请从头到尾阅读我的问题,您将轻松了解我想知道的内容
  • @AdityaSharma - 您需要指定一个连接字符串。如果没有一些编码,您将无法将 lambda 函数与 MongoDB 集成。祝你一切顺利!
【解决方案2】:

我看到您在处理程序范围之外定义了 cachedDb 变量,以便在重用容器时使其可用。但是,不能保证容器会被重用(请参阅我之前的链接),因为这不是 Lambda 的工作方式。如果您在彼此之后非常快速地多次调用相同的函数,则 Lambda 需要横向扩展才能快速处理请求。他们每个人都有自己的容器和连接。

调用完成后,AWS 会保留容器一段时间(多长时间取决于函数大小和 RAM 限制等许多因素)。如果您再次调用它,容器可以重用它们的连接。您可以尝试以 1 秒的间隔调用该函数 20 次,并计算已打开的连接数。它会低于 20,但高于 1。

【讨论】:

    猜你喜欢
    • 2019-03-14
    • 2018-07-23
    • 1970-01-01
    • 2020-11-30
    • 2019-07-27
    • 2020-10-16
    • 2020-09-02
    • 2019-11-02
    相关资源
    最近更新 更多