Nodejs에서 MongoDB 데이터베이스 연결을 닫는 시기
Node MongoDB 네이티브 드라이버를 통해 Nodejs 및 MongoDB 사용.일부 문서를 검색하여 수정한 후 다시 저장해야 합니다.다음은 예를 제시하겠습니다.
db.open(function (err, db) {
db.collection('foo', function (err, collection) {
var cursor = collection.find({});
cursor.each(function (err, doc) {
if (doc != null) {
doc.newkey = 'foo'; // Make some changes
db.save(doc); // Update the document
} else {
db.close(); // Closing the connection
}
});
});
});
비동기 특성으로 문서 업데이트 프로세스가 더 오래 걸리면 커서가 문서 끝에 도달하면 데이터베이스 연결이 닫힙니다.모든 업데이트가 데이터베이스에 저장되는 것은 아닙니다.
경우,db.close()
생략하면 모든 문서가 올바르게 업데이트되지만 응용 프로그램이 중단되고 종료되지 않습니다.
카운터를 사용하여 업데이트 수를 추적하고 0으로 돌아가면 DB를 닫는다는 게시물을 보았습니다.지만 내내 기기 기못 못? ???이런 상황에 대처하는 가장 좋은 방법은 무엇일까요?db.close()
자원을 해방하기 위해 사용해야만 합니까?DB? DB?
다음은 계산 접근법에 기초한 잠재적인 해결책입니다(테스트를 하지 않았고 오류 트래핑은 없지만 아이디어를 전달할 수 있습니다).
기본 전략은 갱신할 레코드 수를 취득하여 각 레코드를 비동기적으로 저장하고 성공 시 콜백을 하는 것입니다.이 경우 카운트가 0에 도달하면(마지막 업데이트가 완료되면) DB가 닫힙니다.「」를 사용해 .{safe:true}
각 업데이트가 성공하는지 확인할 수 있습니다.
mongo 서버는 접속마다 1개의 스레드를 사용하기 때문에 a) 사용하지 않는 연결을 닫거나 b) 풀링/재사용하는 것이 좋습니다.
db.open(function (err, db) {
db.collection('foo', function (err, collection) {
var cursor = collection.find({});
cursor.count(function(err,count)){
var savesPending = count;
if(count == 0){
db.close();
return;
}
var saveFinished = function(){
savesPending--;
if(savesPending == 0){
db.close();
}
}
cursor.each(function (err, doc) {
if (doc != null) {
doc.newkey = 'foo'; // Make some changes
db.save(doc, {safe:true}, saveFinished);
}
});
})
});
});
풀링된 연결을 사용한 후 응용 프로그램 수명 만료 시 정리 함수로 db.close()를 호출하는 것이 가장 좋습니다.
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
http://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html 를 참조해 주세요.
좀 오래된 실타래지만 어쨌든.
다음은 pkopac의 답변에 대한 확장 예입니다. 나머지 세부 사항을 파악해야 했기 때문입니다.
const client = new MongoClient(uri);
(async () => await client.connect())();
// use client to work with db
const find = async (dbName, collectionName) => {
try {
const collection = client.db(dbName).collection(collectionName);
const result = await collection.find().toArray()
return result;
} catch (err) {
console.error(err);
}
}
const cleanup = (event) => { // SIGINT is sent for example when you Ctrl+C a running process from the command line.
client.close(); // Close MongodDB Connection when Process ends
process.exit(); // Exit with default success-code '0'.
}
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
다음 링크에서 다음 링크와 다음 링크의 차이점을 나타냅니다. SIGINT
★★★★★★★★★★★★★★★★★」SIGTERM
'를 했어요.process.exit()
웹 Ctrl + C
명령줄에서 실행 중인 프로세스로 이동합니다.
카운터를 사용하는 것은 간단한 시나리오에 해당할 수 있지만, 복잡한 상황에서는 어려울 수 있다는 것을 알았습니다.다음은 데이터베이스 연결이 유휴 상태일 때 데이터베이스 연결을 닫으면 나타나는 해결 방법입니다.
var dbQueryCounter = 0;
var maxDbIdleTime = 5000; //maximum db idle time
var closeIdleDb = function(connection){
var previousCounter = 0;
var checker = setInterval(function(){
if (previousCounter == dbQueryCounter && dbQueryCounter != 0) {
connection.close();
clearInterval(closeIdleDb);
} else {
previousCounter = dbQueryCounter;
}
}, maxDbIdleTime);
};
MongoClient.connect("mongodb://127.0.0.1:27017/testdb", function(err, connection)(
if (err) throw err;
connection.collection("mycollection").find({'a':{'$gt':1}}).toArray(function(err, docs) {
dbQueryCounter ++;
});
//do any db query, and increase the dbQueryCounter
closeIdleDb(connection);
));
이것은 모든 데이터베이스 연결에 대한 일반적인 솔루션이 될 수 있습니다. maxDbIdleTime은 db 쿼리 시간 초과와 동일한 값으로 설정할 수 있습니다.
이것은 그다지 우아한 것은 아니지만, 이것을 하는 더 좋은 방법이 생각나지 않는다.NodeJs를 사용하여 MongoDb와 Mysql을 쿼리하는 스크립트를 실행합니다.데이터베이스 접속이 정상적으로 닫히지 않으면 스크립트는 영원히 정지됩니다.
내가 생각해낸 해결책이 있어.ToArray를 사용하지 않고 매우 짧고 달콤합니다.
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost:27017/mydb", function(err, db) {
let myCollection = db.collection('myCollection');
let query = {}; // fill in your query here
let i = 0;
myCollection.count(query, (err, count) => {
myCollection.find(query).forEach((doc) => {
// do stuff here
if (++i == count) db.close();
});
});
});
저는 이런 카운터가 포함된 해결책을 생각해 냈습니다.count() 콜에 의존하거나 타임아웃을 기다리지 않습니다.각()의 모든 문서가 소진되면 db가 닫힙니다.
var mydb = {}; // initialize the helper object.
mydb.cnt = {}; // init counter to permit multiple db objects.
mydb.open = function(db) // call open to inc the counter.
{
if( !mydb.cnt[db.tag] ) mydb.cnt[db.tag] = 1;
else mydb.cnt[db.tag]++;
};
mydb.close = function(db) // close the db when the cnt reaches 0.
{
mydb.cnt[db.tag]--;
if ( mydb.cnt[db.tag] <= 0 ) {
delete mydb.cnt[db.tag];
return db.close();
}
return null;
};
따라서 db.each() 또는 db.save()와 같은 콜을 할 때마다 이러한 메서드를 사용하여 db가 동작 중에 준비되고 종료되는 것을 확인합니다.
OP의 예:
foo = db.collection('foo');
mydb.open(db); // *** Add here to init the counter.**
foo.find({},function(err,cursor)
{
if( err ) throw err;
cursor.each(function (err, doc)
{
if( err ) throw err;
if (doc != null) {
doc.newkey = 'foo';
mydb.open(db); // *** Add here to prevent from closing prematurely **
foo.save(doc, function(err,count) {
if( err ) throw err;
mydb.close(db); // *** Add here to close when done. **
});
} else {
mydb.close(db); // *** Close like this instead. **
}
});
});
여기서 두 번째 콜백은 mydb.open()을 경유하여 각 콜백의 마지막 콜백이 mydb.close()로 전송되는 것을 전제로 하고 있습니다.그러므로 물론 이것이 문제인지 여부를 알려 주십시오.
따라서 mydb.open(db)을 db콜 앞에 배치하고 mydb.close(db)를 콜백의 리턴 포인트 또는 db콜 뒤에 배치합니다(콜 유형에 따라 다름).
이 카운터는 db 오브젝트 내에서 유지되어야 한다고 생각합니다만, 이것이 현재의 회피책입니다.constructor에 db를 넣고 mongodb 함수를 랩하여 닫기를 더 잘 처리할 수 있는 새로운 객체를 만들 수 있습니다.
위의 @mpobrien의 제안을 바탕으로 비동기 모듈이 이 점에 매우 도움이 된다는 것을 알게 되었습니다.다음은 제가 채택하게 된 패턴의 예입니다.
const assert = require('assert');
const async = require('async');
const MongoClient = require('mongodb').MongoClient;
var mongodb;
async.series(
[
// Establish Covalent Analytics MongoDB connection
(callback) => {
MongoClient.connect('mongodb://localhost:27017/test', (err, db) => {
assert.equal(err, null);
mongodb = db;
callback(null);
});
},
// Insert some documents
(callback) => {
mongodb.collection('sandbox').insertMany(
[{a : 1}, {a : 2}, {a : 3}],
(err) => {
assert.equal(err, null);
callback(null);
}
)
},
// Find some documents
(callback) => {
mongodb.collection('sandbox').find({}).toArray(function(err, docs) {
assert.equal(err, null);
console.dir(docs);
callback(null);
});
}
],
() => {
mongodb.close();
}
);
카운터, 라이브러리 또는 커스텀 코드를 사용하지 않고 이를 수행하는 현대적인 방법:
let MongoClient = require('mongodb').MongoClient;
let url = 'mongodb://yourMongoDBUrl';
let database = 'dbName';
let collection = 'collectionName';
MongoClient.connect(url, { useNewUrlParser: true }, (mongoError, mongoClient) => {
if (mongoError) throw mongoError;
// query as an async stream
let stream = mongoClient.db(database).collection(collection)
.find({}) // your query goes here
.stream({
transform: (readElement) => {
// here you can transform each element before processing it
return readElement;
}
});
// process each element of stream (async)
stream.on('data', (streamElement) => {
// here you process the data
console.log('single element processed', streamElement);
});
// called only when stream has no pending elements to process
stream.once('end', () => {
mongoClient.close().then(r => console.log('db successfully closed'));
});
});
버전 3.2.7의 mongodb 드라이버로 테스트했지만 링크에 따라 버전 2.0부터 유효할 수 있습니다.
언급URL : https://stackoverflow.com/questions/8373905/when-to-close-mongodb-database-connection-in-nodejs
'programing' 카테고리의 다른 글
iOS WebApp(PWA)에 푸시 알림을 보내는 방법 (0) | 2023.03.07 |
---|---|
Manage widgets from page edit screen (0) | 2023.03.07 |
$resource 서비스를 사용하는 AngularJS.GET 요청으로 약속이 해결되지 않음 (0) | 2023.03.07 |
약속을 어디에 쓰나요? (0) | 2023.03.07 |
Chrome 개발자 도구에서 Ajax 요청 취소 (0) | 2023.03.07 |