简体   繁体   English

aws-serverless-express 连接到 mongo 并获取 mongo 文档

[英]aws-serverless-express connecting to mongo and get mongo document

I am trying to make a Lambda proxy with express using the aws-serverless-express node module.我正在尝试使用 aws-serverless-express 节点模块使用 express 制作 Lambda 代理。 However I keep getting the error 'Error: socket hang up' and I don't know why.但是我不断收到错误“错误:套接字挂断”,我不知道为什么。

Here is my lambda code:这是我的 lambda 代码:

 const app = require('./app');
 const awsServerlessExpress = require('aws-serverless-express');
 const server = awsServerlessExpress.createServer(app);

 exports.handler = (event, context, callback) => {
  console.log('EVENT: ' + JSON.stringify(event));
  awsServerlessExpress.proxy(server, event, context);
}

and here is my express code:这是我的快递代码:

MongoClient.connect("mongodb:/mongoUriGoesHere", function(err, db) {
if(err) { return console.dir(err); }

let collection = db.collection('collection');

app.get('/hello', (req, res) => {
 collection.find().toArray()
  .then((documents) => /* Handle success (console.log) */)
  .catch((err) => /* Handle error */)
 })
});

module.exports = app;

This is my response from the lambda这是我对 lambda 的回应

https://i.stack.imgur.com/Y0ybB.png https://i.stack.imgur.com/Y0ybB.png

I know lambda functions are supposed to be stateless when creating a connection to a db, but I don't know how to get this to work.我知道 lambda 函数在创建到数据库的连接时应该是无状态的,但我不知道如何让它工作。 I've also tried using mongoose and no luck.我也试过使用猫鼬,但没有运气。 I can get it to work when there is no code that attemps to connect to the db, but this is my problem at the moment.当没有尝试连接到数据库的代码时,我可以让它工作,但目前这是我的问题。 Any answers would be greatly appreaciated.任何答案将不胜感激。 Been at this for a while and still can't figure it out!已经在这一段时间了,仍然无法弄清楚!

Lambda is a little strange in how it works under the hood and is not documented as well as it should be. Lambda 在其底层工作方式方面有点奇怪,并且没有像应有的那样进行记录。

Lambda has hot and cold states. Lambda 有态和态。 If it's not invoked for 15 minutes it goes cold otherwise it reuses certain parts of your code and your setup every time it is invoked and refreshes the hot state timeout.如果它在 15 分钟内没有被调用,它就会变冷,否则它会在每次调用时重用代码和设置的某些部分,并刷新热状态超时。

Lambda will not re-execute the bits of your code that sit outside your handler function. Lambda不会重新执行位于handler函数之外的代码位。 Which means that the database connection code you defined will only run once and the code will try to re-use that connection for however long the lambda is hot.这意味着您定义的数据库连接代码将只运行一次,并且代码将尝试重新使用该连接,无论 lambda 是热的多久。

So if there is a connection timeout on MongoClient then it's going to time out your connection but the connection code is not going to re-execute meaning you will get an error saying the expected connection cannot be utilized.因此,如果 MongoClient 上存在连接超时,那么它将使您的连接超时,但连接代码不会重新执行,这意味着您将收到一条错误消息,指出无法使用预期的连接。

Why does all express code not work in this way?为什么所有的快递代码都不能这样工作? It's because when you're defining your middleware eg app.get('/hello', (req, res) => {} this code is only instantiated inside of the lambda handler which means it will re-execute every time.这是因为当您定义中间件时,例如app.get('/hello', (req, res) => {}这段代码仅在 lambda 处理程序内部实例化,这意味着它每次都会重新执行。

The only workaround for this problem that I could come up with is putting your connection command inside the express middleware like this:我能想出的解决此问题的唯一方法是将您的连接命令放入 express 中间件中,如下所示:

app.use(async function (req, res, next) {
    await mongoose.connect(config.database.mongodb.url, dbConfig);

    res.on("finish", function () {
        if(mongoose.connection.readyState === 1){
            mongoose.connection.close();
        }
    });

    next();
});

This solution has drawbacks tho.这个解决方案有缺点。 If you have any asynchronous tasks running after you responded to the client then they'll fail because the db connection will be closed by then.如果您在响应客户端后有任何异步任务在运行,那么它们将失败,因为 db 连接将在那时关闭。

Have a look at https://mongoosejs.com/docs/lambda.html and see how they handle the connection.看看https://mongoosejs.com/docs/lambda.html ,看看他们如何处理连接。 They reuse the same connection across all lambdas.它们在所有 lambda 表达式中重用相同的连接。

我认为你必须返回 awsServerlessExpress.proxy 对象

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

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