我在MongoDB中使用node-mongodb-native驱动程序来编写网站。
我对如何管理连接有一些疑问:
仅使用一个MongoDB连接就足以处理所有请求吗?有性能问题吗?如果没有,我可以设置一个全局连接以在整个应用程序中使用吗?
如果没有,如果在请求到达时打开一个新连接,并在处理请求时将其关闭,那会很好吗?打开和关闭连接是否昂贵?
我应该使用全局连接池吗?我听说驱动程序具有本地连接池。这是一个不错的选择吗?
如果使用连接池,应使用多少个连接?
还有其他需要注意的地方吗?
您在应用程序启动并重新使用时,打开一次MongoClient.connectdb对象。每个.connect都不是一个单例连接池。创建一个新的连接池。
因此,要直接回答您的问题,重新使用从
MongoClient.connect()
生成的db对象。与每个数据库操作上的打开/关闭连接相比,这可以为您提供缓冲,并且速度会明显提高。
db
/server.js
import express from 'express';
import Promise from 'bluebird';
import logger from 'winston';
import { MongoClient } from 'mongodb';
import config from './config';
import usersRestApi from './api/users';
const app = express();
app.use('/api/users', usersRestApi);
app.get('/', (req, res) => {
res.send('Hello World');
});
// Create a MongoDB connection pool and start the application
// after the database connection is ready
MongoClient.connect(config.database.url, { promiseLibrary: Promise }, (err, db) => {
if (err) {
logger.warn(`Failed to connect to the database. ${err.stack}`);
}
app.locals.db = db;
app.listen(config.port, () => {
logger.info(`Node.js app is listening at http://localhost:${config.port}`);
});
});
/api/users.js
import { Router } from 'express';
import { ObjectID } from 'mongodb';
const router = new Router();
router.get('/:id', async (req, res, next) => {
try {
const db = req.app.locals.db;
const id = new ObjectID(req.params.id);
const user = await db.collection('user').findOne({ _id: id }, {
email: 1,
firstName: 1,
lastName: 1
});
if (user) {
user.id = req.params.id;
res.send(user);
} else {
res.sendStatus(404);
}
} catch (err) {
next(err);
}
});
export default router;
启动服务器时,请拨打var MongoClient = require('mongodb').MongoClient;
var url = require("../config.json")["MongoDBURL"]
var option = {
db:{
numberOfRetries : 5
},
server: {
auto_reconnect: true,
poolSize : 40,
socketOptions: {
connectTimeoutMS: 500
}
},
replSet: {},
mongos: {}
};
function MongoPool(){}
var p_db;
function initPool(cb){
MongoClient.connect(url, option, function(err, db) {
if (err) throw err;
p_db = db;
if(cb && typeof(cb) == 'function')
cb(p_db);
});
return MongoPool;
}
MongoPool.initPool = initPool;
function getInstance(cb){
if(!p_db){
initPool(cb)
}
else{
if(cb && typeof(cb) == 'function')
cb(p_db);
}
}
MongoPool.getInstance = getInstance;
module.exports = MongoPool;
initPool
然后在任何其他模块中,您都可以执行以下操作:
require("mongo-pool").initPool();
这是基于var MongoPool = require("mongo-pool");
MongoPool.getInstance(function (db){
// Query your MongoDB database.
});
。看一看。
get = () => dbConnectionObject
在飞行中,您的应用程序需要数据库连接时可以简单地调用// runs in boot.js or what ever file your application starts with
const db = require('./myAwesomeDbModule');
db.connect()
.then(() => console.log('database connected'))
.then(() => bootMyApplication())
.catch((e) => {
console.error(e);
// Always hard exit on a database connection error
process.exit(1);
});
。
get()
如果您以与以下相同的方式设置数据库模块,则不仅可以确保除非具有数据库连接,否则应用程序无法启动,您还可以通过全局方式访问数据库连接池,如果您没有连接,将出错。
const db = require('./myAwesomeDbModule');
db.get().find(...)... // I have excluded code here to keep the example simple