为什么建议不要在 Node.js 代码中的任何地方关闭 MongoDB 连接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14495975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is it recommended not to close a MongoDB connection anywhere in Node.js code?
提问by Amol M Kulkarni
Consider following is the Node.js code:
考虑以下是 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
});
}
See the link for best practice, which says not to close any connections
请参阅最佳实践链接,其中说不要关闭任何连接
https://groups.google.com/forum/#!topic/node-mongodb-native/5cPt84TUsVg
https://groups.google.com/forum/#!topic/node-mongodb-native/5cPt84TUsVg
I have seen log file contains following data:
我看到日志文件包含以下数据:
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)
Doesn't this create a overhead on server by opening multiple connection and not closing it, Does it handles connection pooling internally?
这不会通过打开多个连接而不是关闭它来增加服务器的开销,它是否在内部处理连接池?
But in MongoDB Docsit is mentioned "This is normal behavior for applications that do not use request pooling"
但是在MongoDB Docs中提到“这是不使用请求池的应用程序的正常行为”
Can somebody help me understanding this.
有人可以帮助我理解这一点。
回答by christkv
You open a Db connection once with MongoClient and reuse it across your application. If you need to use multiple db's you use the .db function on the Db object to work on a different db using the same underlying pool of connections. A pool is kept to ensure a single blocking operation cannot freeze up your node.js application. Default size if 5 connections in a pool.
您使用 MongoClient 打开一次 Db 连接并在您的应用程序中重复使用它。如果您需要使用多个数据库,您可以在 Db 对象上使用 .db 函数来使用相同的底层连接池处理不同的数据库。保留一个池以确保单个阻塞操作不会冻结您的 node.js 应用程序。如果池中有 5 个连接,则默认大小。
http://mongodb.github.com/node-mongodb-native/driver-articles/mongoclient.html
http://mongodb.github.com/node-mongodb-native/driver-articles/mongoclient.html
I also forgot to add. As the other answer pointed out setting up a new TCP connection is EXPENSIVE timewise and memory wise that's why you reuse connections. Also a new connection will cause a new Thread to be created on MongoDB using memory on the Db as well.
我也忘记补充了。正如另一个答案指出的那样,设置新的 TCP 连接在时间和内存方面都是昂贵的,这就是您重用连接的原因。此外,新连接也会使用 Db 上的内存在 MongoDB 上创建一个新线程。
回答by lindsaymacvean
MongoDB pools database connections to be more efficient, so it is not unusual to have many connections open in the mongodb.log
MongoDB 将数据库连接池化以提高效率,因此在 mongodb.log 中打开许多连接并不罕见
However it is useful to close all connections when your app closes completely. This code is most excellent for doing this.
但是,当您的应用程序完全关闭时关闭所有连接很有用。此代码最适合执行此操作。
process.on('SIGINT', function() {
mongoose.connection.close(function () {
console.log('Mongoose disconnected on app termination');
process.exit(0);
});
});
回答by Sammaye
I am no node.js expert however I think the reason is relatively the same between most languages.
我不是 node.js 专家,但我认为大多数语言之间的原因相对相同。
Making a connection is:
建立连接是:
one of the most heavyweight things that the driver does. It can take hundreds of milliseconds to set up a connection correctly, even on a fast network.
司机所做的最重要的事情之一。即使在快速网络上,正确设置连接也可能需要数百毫秒的时间。
( http://php.net/manual/en/mongo.connecting.pools.php)
( http://php.net/manual/en/mongo.connecting.pools.php)
Provided that is for PHP and the doc is a little out of date that part still applies even now and across most, if not all, drivers.
如果是针对 PHP 并且文档有点过时,那么该部分即使现在也适用于大多数(如果不是全部)驱动程序。
Each connection can also use a separate thread which causes obvious overhead.
每个连接也可以使用单独的线程,这会导致明显的开销。
It seems from:
似乎来自:
That node.js still uses connection pooling to try and stop the overhead of making a connection. This, of course, no longer applies to other drivers like the PHP one.
该 node.js 仍然使用连接池来尝试停止建立连接的开销。当然,这不再适用于其他驱动程序,例如 PHP 驱动程序。
It opens xamount of connections (default is 5) to your database server and transfers work to a free connection when data is needed and so reusing old connections averting this nasty process which can cause those logs: http://docs.mongodb.org/manual/faq/developers/#why-does-mongodb-log-so-many-connection-accepted-eventsand increase connection overhead.
它打开到您的数据库服务器x的连接数量(默认为5),并在需要数据时将工作转移到免费连接,因此重用旧连接避免了可能导致这些日志的讨厌过程:http: //docs.mongodb.org/manual /faq/developers/#why-does-mongodb-log-so-many-connection-accepted-events并增加连接开销。

