programing

Node.js 코드에서 MongoDB 연결을 닫지 않는 것이 권장되는 이유는 무엇입니까?

lastmoon 2023. 3. 13. 20:46
반응형

Node.js 코드에서 MongoDB 연결을 닫지 않는 것이 권장되는 이유는 무엇입니까?

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에서는 "이는 요청 풀링을 사용하지 않는 응용 프로그램의 정상적인 동작"이라고 언급되어 있습니다.

누가 이걸 이해하는데 좀 도와줄래?

MongoClient에서 DB 연결을 한 번 열고 응용 프로그램에서 다시 사용할 수 있습니다.여러 개의 db를 사용해야 하는 경우 동일한 기본 연결 풀을 사용하여 다른 db에서 작업하려면 Db 개체의 .db 함수를 사용합니다.단일 차단 작업으로 node.js 응용 프로그램을 프리즈업할 수 없도록 하기 위해 풀이 유지됩니다.풀에 5개의 연결이 있는 경우의 기본 크기입니다.

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

덧붙이는 것도 까먹었어요.다른 답변에서 지적했듯이 새로운 TCP 접속을 설정하는 것은 시간적으로나 메모리로나 비용이 많이 들기 때문에 접속을 재사용할 수 있습니다.또, 새로운 접속에 의해서, Db상의 메모리를 사용해 MongoDB상에 새로운 스레드가 작성됩니다.

MongoDB는 데이터베이스 접속을 보다 효율적으로 풀링하기 때문에 mongodb.log에서 많은 접속이 열려 있는 것은 드문 일이 아닙니다.

그러나 앱이 완전히 닫히면 모든 연결을 닫는 것이 유용합니다.이 코드는 이 작업에 가장 적합합니다.

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

저는 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데이터가 필요할 때 작업을 데이터베이스 서버로 전송하고 오래된 연결을 재사용하여 로그의 원인이 될 수 있는 이 귀찮은 프로세스를 회피합니다.

https://docs.mongodb.com/manual/faq/diagnostics/ #why-does-mongodb-log-so-many-connection-mongodb-log-so-many-many-

프로그램 종료 시 mongo 접속을 끊고 프로그램 실행 시 접속을 1개만 확립하고 싶다면 다음 싱글톤을 작성할 것을 권장합니다(불행하게도 이것은 노드가 아닌 python으로 되어 있지만 동일한 개념이 적용됩니다).

import atexit

class MongoDB:
'''define class attributes'''
__instance = None

@staticmethod
def getInstance():
    """ Static access method. """
    # if the instance doesnt exist envoke the constructor
    if MongoDB.__instance == None:
        MongoDB()
    # return instance
    return MongoDB.__instance

def __init__(self) -> None:
    """ Virtually private constructor. """
    if MongoDB.__instance != None:
        raise Exception("Singleton cannot be instantiated more than once")

    else:
        print("Creating MongoDB connection")
        # set instance and instance attributes
        self.client = MongoClient(config.CONNECTION_STRING)
        MongoDB.__instance = self


@staticmethod
@atexit.register
def closeConnection():
    ''' 
    Python '__del__' aka destructor dunder doesnt always get called
    mainly when program is terminated by ctrl-c so this method is decorated
    by 'atexit' which ensures this method is called upon program termination
    '''
    if MongoDB.__instance != None:
        MongoDB.__instance.client.close()
        print("Closing Connections")

이것은 프로그램 종료 시 모든 접속이 끊어지고 동일한 접속 인스턴스가 공유되도록 하기 위한 좋은 설계 패턴이며, 앞서 말한 것처럼 한 번만 데이터베이스에 접속하는 것이 가장 비용이 많이 드는 작업이라고 생각합니다.

언급URL : https://stackoverflow.com/questions/14495975/why-is-it-recommended-not-to-close-a-mongodb-connection-anywhere-in-node-js-code

반응형