Node.js AWS Lambda数据库连接问题[更新问题]
我有一个aws lambda函数,当它点击请求时返回null。在建立数据库连接之前,我对请求的测试一直有效。有没有想过为什么它没有运行请求 日志将就绪状态显示为1,然后返回null ***编辑 这是第一个问题,一旦我答应了它,我就遇到了在执行模式方法之前数据库连接消失的问题。我将在下面回答Node.js AWS Lambda数据库连接问题[更新问题],node.js,mongodb,amazon-web-services,lambda,request,Node.js,Mongodb,Amazon Web Services,Lambda,Request,我有一个aws lambda函数,当它点击请求时返回null。在建立数据库连接之前,我对请求的测试一直有效。有没有想过为什么它没有运行请求 日志将就绪状态显示为1,然后返回null ***编辑 这是第一个问题,一旦我答应了它,我就遇到了在执行模式方法之前数据库连接消失的问题。我将在下面回答 const request = require('request') const tickerController = require('./controllers/ticker'); const mong
const request = require('request')
const tickerController = require('./controllers/ticker');
const mongoose = require('mongoose');
let conn = null;
const uri = `mongodb+srv://${process.env.dbUser}:${process.env.dbPassword}@cluster0-oj6p1.mongodb.net/test?retryWrites=true&w=majority`;
exports.handler = async function main(event, context, lambdaCallback) {
// Make sure to add this so you can re-use `conn` between function calls.
// See https://www.mongodb.com/blog/post/serverless-development-with-nodejs-aws-lambda-mongodb-atlas
context.callbackWaitsForEmptyEventLoop = false;
// Because `conn` is in the global scope, Lambda may retain it between
// function calls thanks to `callbackWaitsForEmptyEventLoop`.
// This means your Lambda function doesn't have to go through the
// potentially expensive process of connecting to MongoDB every time.
if (conn == null) {
conn = await mongoose.createConnection(uri, {
// Buffering means mongoose will queue up operations if it gets
// disconnected from MongoDB and send them when it reconnects.
// With serverless, better to fail fast if not connected.
bufferCommands: false, // Disable mongoose buffering
bufferMaxEntries: 0, // and MongoDB driver buffering
useUnifiedTopology: true,
useNewUrlParser: true
});
// conn.model('Test', new mongoose.Schema({ name: String }));
// console.log(conn);
console.log(conn.readyState);
runRequest(lambdaCallback);
// })
}
};
function runRequest(lambdaCallback) {
request('https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=BKUH&apikey=' + process.env.apiKey, (err, response, body) => {
console.log('Request ran');
if (err) {
console.error(err);
done(502, '{"message", "Error retrieving ticker data"}', 'application/json', lambdaCallback);
} else {
try {
.....
我将开始使用promissions/async/await而不是回调模式。差不多
const request = require("request");
const tickerController = require("./controllers/ticker");
const mongoose = require("mongoose");
let conn = null;
const uri = `mongodb+srv://${process.env.dbUser}:${process.env.dbPassword}@cluster0-oj6p1.mongodb.net/test?retryWrites=true&w=majority`;
exports.handler = async event => {
// Make sure to add this so you can re-use `conn` between function calls.
// See https://www.mongodb.com/blog/post/serverless-development-with-nodejs-aws-lambda-mongodb-atlas
context.callbackWaitsForEmptyEventLoop = false;
// Because `conn` is in the global scope, Lambda may retain it between
// function calls thanks to `callbackWaitsForEmptyEventLoop`.
// This means your Lambda function doesn't have to go through the
// potentially expensive process of connecting to MongoDB every time.
if (conn == null) {
conn = await mongoose.createConnection(uri, {
// Buffering means mongoose will queue up operations if it gets
// disconnected from MongoDB and send them when it reconnects.
// With serverless, better to fail fast if not connected.
bufferCommands: false, // Disable mongoose buffering
bufferMaxEntries: 0, // and MongoDB driver buffering
useUnifiedTopology: true,
useNewUrlParser: true
});
// conn.model('Test', new mongoose.Schema({ name: String }));
// console.log(conn);
console.log(conn.readyState);
const body = await runRequest();
return body;
// })
}
};
function runRequest() {
return new Promise((resolve, reject) => {
request(
"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=BKUH&apikey=" +
process.env.apiKey,
(err, response, body) => {
console.log("Request ran");
if (err) {
console.error(err);
reject(err);
}
resolve(body);
}
);
});
}
因此,数据库连接问题的答案是将代码重构为一个文件,并使用“conn”变量作为全局对象来创建模型,如下所示
let conn = null;
let Ticker = null;
const uri = `mongodb+srv://${process.env.dbUser}:${process.env.dbPassword}@cluster0-oj6p1.mongodb.net/bakhu?retryWrites=true&w=majority`;
exports.handler = async function main(event, context, lambdaCallback) {
// Make sure to add this so you can re-use `conn` between function calls.
// See https://www.mongodb.com/blog/post/serverless-development-with-nodejs-aws-lambda-mongodb-atlas
context.callbackWaitsForEmptyEventLoop = false;
// Because `conn` is in the global scope, Lambda may retain it between
// function calls thanks to `callbackWaitsForEmptyEventLoop`.
// This means your Lambda function doesn't have to go through the
// potentially expensive process of connecting to MongoDB every time.
if (conn == null) {
conn = await mongoose.createConnection(uri, {
// Buffering means mongoose will queue up operations if it gets
// disconnected from MongoDB and send them when it reconnects.
// With serverless, better to fail fast if not connected.
bufferCommands: false, // Disable mongoose buffering
bufferMaxEntries: 0, // and MongoDB driver buffering
useUnifiedTopology: true,
useNewUrlParser: true
});
// conn.model('Test', new mongoose.Schema({ name: String }));
// console.log(conn);
console.log(conn.readyState);
const Schema = mongoose.Schema;
const moment = require('moment');
const tickerSchema = new Schema({
createdAt: { type: Date },
updatedAt: { type: Date },
symbol: { type: String },
latestPrice: { type: String }
});
tickerSchema.pre('save', function (next) {
let ticker = this;
this.createdAt = ticker.createdAt ? ticker.createdAt : moment().local();
this.updatedAt = moment().local();
next();
})
Ticker = conn.model('Ticker', tickerSchema);
当我在一个单独的文件中调用我的模式方法时,它从未共享连接。哪里是
done
的来源?done是我编写的一个函数。我解决了这个问题,我将写在下面。在回答您自己的问题时,使用承诺会在访问SchemaGrats之前断开数据库连接,这是一个问题!谢谢分享你的发现。