为什么建议不要在Node.js代码中的任何地方关闭MongoDB连接?

Amo*_*rni 53 mongodb node.js

请考虑以下是Node.js代码:

function My_function1(_params) {
    db.once('open', function (err){
     //Do some task 1
});
}

function My_function2(_params) {
    db.once('open', function (err){
     //Do some task 2
});
}
Run Code Online (Sandbox Code Playgroud)

请参阅最佳做法链接,该链接表示不要关闭任何连接

https://groups.google.com/forum/#!topic/node-mongodb-native/5cPt84TUsVg

我见过日志文件包含以下数据:

Fri Jan 18 11:00:03 Trying to start Windows service 'MongoDB'
Fri Jan 18 11:00:03 Service running
Fri Jan 18 11:00:03 [initandlisten] MongoDB starting : pid=1592 port=27017 dbpath=\data\db\ 64-bit host=AMOL-KULKARNI
Fri Jan 18 11:00:03 [initandlisten] db version v2.2.1, pdfile version 4.5
Fri Jan 18 11:00:03 [initandlisten] git version: d6...e0685521b8bc7b98fd1fab8cfeb5ae
Fri Jan 18 11:00:03 [initandlisten] build info: windows sys.getwindowsversion(major=6, minor=1, build=7601, platform=2, service_pack='Service Pack 1') BOOST_LIB_VERSION=1_49
Fri Jan 18 11:00:03 [initandlisten] options: { config: "c:\mongodb\mongod.cfg", logpath: "c:\mongodb\log\mongo.log", service: true }
Fri Jan 18 11:00:03 [initandlisten] journal dir=/data/db/journal
Fri Jan 18 11:00:03 [initandlisten] recover begin
Fri Jan 18 11:00:04 [initandlisten] recover lsn: 6624179
Fri Jan 18 11:00:04 [initandlisten] recover /data/db/journal/j._0
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section seq:59343 < lsn:6624179
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section seq:118828 < lsn:6624179
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section seq:238138 < lsn:6624179
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section seq:835658 < lsn:6624179
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section seq:955218 < lsn:6624179
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section seq:3467218 < lsn:6624179
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section seq:3526418 < lsn:6624179
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section seq:3646154 < lsn:6624179
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section seq:3705844 < lsn:6624179
Fri Jan 18 11:00:04 [initandlisten] recover skipping application of section more...
Fri Jan 18 11:00:05 [initandlisten] recover cleaning up
Fri Jan 18 11:00:05 [initandlisten] removeJournalFiles
Fri Jan 18 11:00:05 [initandlisten] recover done
Fri Jan 18 11:00:10 [initandlisten] query MYDB.system.namespaces query: { options.temp: { $in: [ true, 1 ] } } ntoreturn:0 ntoskip:0 nscanned:5 keyUpdates:0  nreturned:0 reslen:20 577ms
Fri Jan 18 11:00:10 [initandlisten] waiting for connections on port 27017
Fri Jan 18 11:00:10 [websvr] admin web console waiting for connections on port 28017
Fri Jan 18 11:01:10 [PeriodicTask::Runner] task: WriteBackManager::cleaner took: 32ms
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50076 #1 (1 connection now open)
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50077 #2 (2 connections now open)
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50078 #3 (3 connections now open)
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50079 #4 (4 connections now open)
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50080 #5 (5 connections now open)
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50081 #6 (6 connections now open)
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50082 #7 (7 connections now open)
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50083 #8 (8 connections now open)
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50084 #9 (9 connections now open)
Fri Jan 18 13:36:27 [initandlisten] connection accepted from 192.168.0.1:50085 #10 (10 connections now open)
...........................................
Fri Jan 18 13:36:48 [initandlisten] connection accepted from 192.168.0.1:50092 #97 (97 connections now open)
Run Code Online (Sandbox Code Playgroud)

这不会通过打开多个连接而不关闭它来在服务器上创建开销,它是否在内部处理连接池?

但在MongoDB Docs中提到"对于不使用请求池的应用程序,这是正常行为"

有人可以帮助我理解这一点.

小智 54

您使用MongoClient打开一次Db连接,并在整个应用程序中重复使用它.如果需要使用多个db,则可以使用Db对象上的.db函数,使用相同的基础连接池在不同的数据库上工作.保留一个池以确保单个阻塞操作不会冻结您的node.js应用程序.如果池中有5个连接,则为默认大小.

http://mongodb.github.com/node-mongodb-native/driver-articles/mongoclient.html

我也忘了加.正如另一个答案所指出的那样,设置一个新的TCP连接是时间和内存方式的EXPENSIVE,这就是重用连接的原因.此外,新连接将导致使用Db上的内存在MongoDB上创建新线程.

  • 我刚刚建立了cron任务,每次都重新连接到mongo。存档一些东西是一项快速的任务。每次重新连接时,任务大约需要15-25毫秒。重新使用连接大约需要0-1ms。因此,这是现实世界的差异:重复使用连接时速度提高15-25倍。当然有人会说25毫秒足够快,但是为什么即使在简单的任务上也要消耗更多的资源呢?只是重用连接。做完了 (3认同)

lin*_*ean 13

MongoDB使数据库连接更加高效,因此在mongodb.log中打开许多连接并不罕见

但是,当您的应用完全关闭时关闭所有连接很有用.这段代码非常适合这样做.

process.on('SIGINT', function() {
  mongoose.connection.close(function () {
    console.log('Mongoose disconnected on app termination');
    process.exit(0);
  });
});
Run Code Online (Sandbox Code Playgroud)

  • 因此,有效而严格的方法是:[1]打开连接;[2]对所有数据库操作使用相同的连接,直到计划退出脚本为止。[3]仅在计划退出脚本时关闭连接。我理解正确吗? (2认同)
  • @eugensunic ...我发现,如果您无法在node.js脚本中关闭MongoDB连接,即使该脚本执行完毕,该脚本也会保留在Node的滴答队列中。结果是服务器一直在等待节点完成,并且因为这种情况永远不会发生,所以最终会导致AJAX超时失败。 (2认同)

Sam*_*aye 9

我不是node.js专家,但我认为大多数语言之间的原因相对相同.

建立联系是:

司机所做的最重量级的事情之一.即使在快速网络上,也可能需要数百毫秒才能正确设置连接.

(http://php.net/manual/en/mongo.connecting.pools.php)

如果是针对PHP并且doc有点过时,那么即使现在和大多数(如果不是全部)驱动程序仍然适用.

每个连接也可以使用单独的线程,这会导致明显的开销.

它似乎来自:

http://mongodb.github.com/node-mongodb-native/driver-articles/mongoclient.html#the-url-connection-format

node.js仍然使用连接池来尝试停止建立连接的开销.当然,这不再适用于PHP之类的其他驱动程序.

它打开x5数据库服务器的连接数量(默认为),并在需要数据时将工作转移到空闲连接,因此重用旧连接以避免可能导致这些日志的恶劣过程:http://docs.mongodb.org/manual/faq/developers /#why-does-mongodb-log-so-many-connection-accepted-events并增加连接开销.