Nodejs mongoose的问题,每次增删改查都要打开关闭连接吗?

发布于 1周前 作者 zlyuanteng 来自 nodejs/Nestjs

Nodejs mongoose的问题,每次增删改查都要打开关闭连接吗?

问题

同问,mongoos的问题,每次增删改查都要打开关闭时吗?

问题是,我不关,他就挂在那了。。

我的解决方案

使用mongoose内置的连接池,配置如下

options = {  
  server: {
    auto_reconnect: true,
    poolSize: 10
  }
};

说明:

  • poolSize是连接池大小
  • auto_reconnect是否自动重连接

代码

// mongoose config
var mongoose = require('mongoose')  
  , connectionString = 'mongodb://localhost:27017/exam_weixin'
  , options = {};

options = {
server: { auto_reconnect: true, poolSize: 10 } };

mongoose.connect(connectionString, options, function(err, res) {
if(err) { console.log(’[mongoose log] Error connecting to: + connectionString + ‘. + err); } else { console.log(’[mongoose log] Successfully connected to: + connectionString); } });

var db = mongoose.connection; db.on(‘error’, console.error.bind(console, mongoose connection error:’)); db.once(‘open’, function callback () { // yay! console.log(‘mongoose open success’); });

还有更好的方案?

请不吝赐教


7 回复

Nodejs mongoose的问题,每次增删改查都要打开关闭连接吗?

问题

同问,Mongoose的问题,每次增删改查都要打开关闭连接吗?

问题是,我不关,他就挂在那了。

我的解决方案

使用 Mongoose 内置的连接池,配置如下:

const options = {  
  server: {
    auto_reconnect: true,
    poolSize: 10
  }
};

说明:

  • poolSize 是连接池大小。
  • auto_reconnect 是否自动重连接。

代码

// mongoose config
const mongoose = require('mongoose');  
const connectionString = 'mongodb://localhost:27017/exam_weixin';
const options = {};

options.server = {
  auto_reconnect: true,
  poolSize: 10
};

mongoose.connect(connectionString, options, function(err, res) {  
  if (err) {
    console.log('[mongoose log] Error connecting to: ' + connectionString + '. ' + err);
  } else {
    console.log('[mongoose log] Successfully connected to: ' + connectionString);
  }
});

const db = mongoose.connection;

db.on('error', console.error.bind(console, 'mongoose connection error:'));
db.once('open', function callback() {
  console.log('mongoose open success');
});

还有更好的方案?

通常情况下,不需要每次都手动打开和关闭 MongoDB 的连接。Mongoose 默认会管理连接池,并且在应用启动时连接到数据库,在应用退出时关闭连接。因此,你可以将连接逻辑放在一个单独的文件中,例如 db.js,并在应用启动时调用它。

例如,创建一个 db.js 文件:

const mongoose = require('mongoose');

const connectDB = async () => {
  try {
    await mongoose.connect('mongodb://localhost:27017/exam_weixin', {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      server: {
        auto_reconnect: true,
        poolSize: 10
      }
    });
    console.log('MongoDB connected successfully');
  } catch (err) {
    console.error(`Error connecting to MongoDB: ${err.message}`);
    process.exit(1);
  }
};

module.exports = connectDB;

然后在你的主文件(如 app.js)中调用这个函数:

const express = require('express');
const connectDB = require('./db');

const app = express();

connectDB().then(() => {
  app.listen(3000, () => {
    console.log('Server is running on port 3000');
  });
}).catch((err) => {
  console.error(`Failed to start the server: ${err.message}`);
});

这样,你就可以确保在应用启动时建立连接,并在应用退出时关闭连接。


cnode 好像连连接池都没用。。

我查了下,默认 pool 是 5。http://mongoosejs.com/docs/connections.html 线上应该够用了。有一次我看乌云上,一个线上服务的配置流出,那个服务访问量也不算小了,pool size 也是 5。

关于 pool size 的大小,这个回答不错。

The optimum size of a thread pool depends on the number of processors available and the nature of the tasks on the work queue. On an N-processor system for a work queue that will hold entirely compute-bound tasks, you will generally achieve maximum CPU utilization with a thread pool of N or N+1 threads. For tasks that may wait for I/O to complete – for example, a task that reads an HTTP request from a socket – you will want to increase the pool size beyond the number of available processors, because not all threads will be working at all times. Using profiling, you can estimate the ratio of waiting time (WT) to service time (ST) for a typical request. If we call this ratio WT/ST, for an N-processor system, you’ll want to have approximately N*(1+WT/ST) threads to keep the processors fully utilized. Processor utilization is not the only consideration in tuning the thread pool size. As the thread pool grows, you may encounter the limitations of the scheduler, available memory, or other system resources, such the number of sockets, open file handles, or database connections. So profile your application, if your threads are mostly cpu bound, then set the thread pools size to number of cores, or number of cores + 1. If you are spending most of your time waiting for database calls to complete, then experiment with a fairly large number of threads, and see how the application performs.

如果不关,就是所谓的长连接吧!你使用autoreconnect的目的同样是为了保持数据库一直处于连接状态,这样就不用每次操作都要打开 连接,频繁的打开关闭也会对数据库造成压力

前天面试被问到mongoose连接池配置,我说使用默认的配置,访问没有问题,没有进行特殊设置,然后被鄙视了

回答

在 Node.js 中使用 Mongoose 进行数据库操作时,通常不需要在每次增删改查(CRUD)操作时都手动打开和关闭数据库连接。Mongoose 本身提供了连接池功能,可以管理数据库连接的生命周期。

解释

  1. 连接池:Mongoose 使用 MongoDB 的连接池机制来管理多个并发连接。通过设置 poolSize 可以控制连接池中最多有多少个活动连接。
  2. 自动重连:设置 auto_reconnecttrue 可以让 Mongoose 在网络中断或数据库重启时自动重新连接。

示例代码

const mongoose = require('mongoose');

// MongoDB 连接字符串
const connectionString = 'mongodb://localhost:27017/mydatabase';

// 配置选项
const options = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  server: {
    auto_reconnect: true,
    poolSize: 10
  }
};

// 连接到 MongoDB
mongoose.connect(connectionString, options, (err) => {
  if (err) {
    console.error('Failed to connect to MongoDB:', err);
  } else {
    console.log('Successfully connected to MongoDB');
  }
});

// 创建一个简单的 Schema 和 Model
const userSchema = new mongoose.Schema({
  name: String,
  age: Number
});

const User = mongoose.model('User', userSchema);

// 增加数据
async function addUser() {
  const newUser = new User({ name: 'John Doe', age: 30 });
  await newUser.save();
}

// 查询数据
async function getUsers() {
  const users = await User.find({});
  console.log(users);
}

// 更新数据
async function updateUser() {
  await User.updateOne({ name: 'John Doe' }, { $set: { age: 31 }});
}

// 删除数据
async function removeUser() {
  await User.deleteOne({ name: 'John Doe' });
}

// 调用函数进行 CRUD 操作
addUser().then(getUsers).then(updateUser).then(getUsers).then(removeUser).then(() => {
  mongoose.disconnect(); // 在所有操作完成后断开连接
}).catch(console.error);

注意点

  • 连接管理:在应用程序启动时建立连接,并在程序结束前关闭连接。
  • 错误处理:在连接过程中添加适当的错误处理逻辑,以确保不会因为某个错误导致整个应用崩溃。
  • 连接池配置:根据应用需求调整连接池大小,避免资源浪费或耗尽。

以上代码展示了如何在一次连接中完成增删改查操作,并在操作完成后断开连接。这样可以减少连接管理的复杂度,提高性能和可靠性。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!