我正在尝试使用aws-serverless-express节点模块使用express来创建Lambda代理。但是我一直收到错误'错误:socket挂断'而且我不知道为什么。
这是我的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的回应
https://i.stack.imgur.com/Y0ybB.png
我知道在创建与db的连接时,lambda函数应该是无状态的,但我不知道如何使它工作。我也试过用猫鼬而没有运气。当没有代码试图连接到数据库时,我可以让它工作,但这是我目前的问题。任何答案都会有很大的帮助。已经有一段时间了,仍然无法弄明白!
答案 0 :(得分:0)
我认为你必须返回awsServerlessExpress.proxy对象
答案 1 :(得分:0)
Lambda在引擎盖下的工作方式有点奇怪,并且没有得到应有的记录。
Lambda具有热门和冷状态。如果15分钟未调用它,它将变冷,否则它将在每次调用时重用代码的某些部分和设置,并刷新热状态超时。
Lambda 不会重新执行位于handler
函数外部的代码位。这意味着您定义的数据库连接代码将仅运行一次,并且该代码将在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之间重用相同的连接。