我正在尝试使用 aws-serverless-express Node 模块创建带有 Express 的 Lambda 代理。但是我不断收到错误“错误:套接字挂起”,我不知道为什么。
这是我的 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);
}
这是我的快速代码:
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;
这是我从 lambda 得到的回应
我知道 lambda 函数在创建与数据库的连接时应该是无状态的,但我不知道如何让它工作。我也尝试过使用 Mongoose ,但没有运气。当没有代码尝试连接到数据库时,我可以让它工作,但这是我目前的问题。任何答案将不胜感激。搞了好久了还是没搞明白!
最佳答案
Lambda 的底层工作方式有点奇怪,并且没有得到应有的记录。
Lambda 具有热和冷状态。如果 15 分钟内没有调用它,它就会变冷,否则它会在每次调用时重用代码和设置的某些部分,并刷新热状态超时。
Lambda 不会重新执行处理程序
函数之外的代码部分。这意味着您定义的数据库连接代码只会运行一次,并且无论 lambda 很热,代码都会尝试重复使用该连接。
因此,如果 MongoClient 上存在连接超时,那么它将使您的连接超时,但连接代码不会重新执行,这意味着您将收到一条错误消息,指出无法利用预期的连接。
为什么所有表达代码不能以这种方式工作?
这是因为当您定义中间件时,例如app.get('/hello', (req, res) => {}
此代码仅在 lambda 处理程序内部实例化,这意味着它每次都会重新执行。
我能想到的解决这个问题的唯一方法是将连接命令放入快速中间件中,如下所示:
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();
});
这个解决方案也有缺点。如果在响应客户端后运行任何异步任务,那么它们将失败,因为届时数据库连接将关闭。
看看https://mongoosejs.com/docs/lambda.html并查看他们如何处理连接。他们在所有 lambda 中重复使用相同的连接。
关于javascript - aws-serverless-express 连接到 mongo 并获取 mongo 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44028978/