Почему рекомендуется не закрывать соединение 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
});
}
См. ссылку для лучшей практики, в которой говорится, что нельзя закрыть какие-либо соединения.
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)
Не создает ли это накладные расходы на сервере, открывая несколько соединений и не закрывая его, обрабатывает ли он внутренний пул соединений?
Но в MongoDB Docs упоминается "Это нормальное поведение для приложений, которые не используют пул запросов"
Может кто-нибудь помочь мне понять это.
Ответы
Ответ 1
Вы открываете соединение Db один раз с MongoClient и повторно используете его в своем приложении. Если вам нужно использовать несколько db, вы используете функцию .db для объекта Db для работы с другим db, используя тот же базовый пул соединений. Пул хранится, чтобы гарантировать, что одна операция блокировки не может заморозить ваше приложение node.js. Размер по умолчанию, если 5 подключений в пуле.
http://mongodb.github.com/node-mongodb-native/driver-articles/mongoclient.html
Я тоже забыл добавить. Поскольку в другом ответе указывалось, что настройка нового TCP-соединения является ДОРОГОЙ временной и разумной памятью, почему вы повторно используете соединения. Также новое соединение приведет к созданию нового потока на MongoDB с использованием памяти на Db.
Ответ 2
Я не эксперт node.js, но я думаю, что причина относительно одинакова для большинства языков.
Создание соединения:
одна из самых тяжелых вещей, которые делает водитель. Для правильной настройки соединения может потребоваться сотни миллисекунд, даже в быстрой сети.
(http://php.net/manual/en/mongo.connecting.pools.php)
При условии, что для PHP и документа немного устарели, эта часть по-прежнему применяется даже сейчас и в большинстве, если не во всех, драйверах.
Каждое соединение может также использовать отдельный поток, который вызывает очевидные накладные расходы.
Кажется, из:
http://mongodb.github.com/node-mongodb-native/driver-articles/mongoclient.html#the-url-connection-format
Чтобы node.js по-прежнему использует пул соединений, чтобы попытаться и остановить накладные расходы на создание соединения. Это, конечно, больше не относится к другим драйверам, таким как PHP.
Он открывает x
количество соединений (по умолчанию - 5
) на сервере базы данных и передает работу на бесплатное соединение, когда необходимы данные, и повторное использование старых соединений, предотвращающих этот неприятный процесс, который может вызвать эти журналы: http://docs.mongodb.org/manual/faq/developers/#why-does-mongodb-log-so-many-connection-accepted-events и увеличить накладные расходы на подключение.
Ответ 3
Соединения базы данных MongoDB более эффективны, поэтому нет ничего необычного в том, чтобы в mongodb.log было открыто несколько соединений
Однако полезно закрыть все соединения, когда ваше приложение полностью закрывается. Этот код является самым превосходным для этого.
process.on('SIGINT', function() {
mongoose.connection.close(function () {
console.log('Mongoose disconnected on app termination');
process.exit(0);
});
});