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 연결을 열어야합니까?
다음은 계산 방식을 기반으로 한 잠재적 인 솔루션입니다 (테스트하지 않았고 오류 트래핑도 없지만 아이디어를 전달해야 함).
기본 전략은 다음과 같습니다. 업데이트해야하는 레코드 수를 수집하고, 각 레코드를 비동기 적으로 저장하고, 성공시 콜백을 저장합니다. 이렇게하면 개수가 감소하고 개수가 0에 도달하면 (마지막 업데이트가 완료 될 때) DB가 닫힙니다. 사용함으로써 {safe:true}
우리는 각 업데이트가 성공적인지 확인할 수 있습니다.
mongo 서버는 연결 당 하나의 스레드를 사용하므로 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 참조
약간 오래된 스레드이지만 어쨌든.
카운터 사용은 간단한 시나리오에 적용될 수 있지만 복잡한 상황에서는 어려울 수 있습니다. 다음은 데이터베이스 연결이 유휴 상태 일 때 데이터베이스 연결을 닫는 솔루션입니다.
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 query timeout과 같은 값 이상으로 설정할 수 있습니다.
이것은 매우 우아하지는 않지만 더 나은 방법을 생각할 수 없습니다. NodeJ를 사용하여 MongoDb 및 Mysql을 쿼리하는 스크립트를 실행하고 데이터베이스 연결이 제대로 닫히지 않으면 스크립트가 영원히 중단됩니다.
위의 @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();
}
);
Here's a solution I came up with. It avoids using toArray and it's pretty short and sweet:
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();
});
});
});
I came up with a solution that involves a counter like this. It does not depend on a count() call nor does it wait for a time out. It will close the db after all the documents in each() are exhausted.
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;
};
So that each time you are going to make a call like db.each() or db.save() you would use these methods to ensure the db is ready while working and closed when done.
Example from 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. **
}
});
});
Now, this assumes that the second to last callback from each makes it through the mydb.open() before the last callback from each goes to mydb.close().... so, of course, let me know if this is an issue.
So: put a mydb.open(db) before a db call and put a mydb.close(db) at the return point of the callback or after the db call (depending on the call type).
Seems to me that this kind of counter should be maintained within the db object but this is my current workaround. Maybe we could create a new object that takes a db in the constructor and wrap the mongodb functions to handle the close better.
참고URL : https://stackoverflow.com/questions/8373905/when-to-close-mongodb-database-connection-in-nodejs
'IT박스' 카테고리의 다른 글
Thread.setPriority ()와 android.os.Process.setThreadPriority ()의 차이점은 무엇입니까? (0) | 2020.11.09 |
---|---|
C # 매트릭스 라이브러리에 대한 권장 사항 (0) | 2020.11.09 |
Java 8 메서드 참조의 MethodInfo를 얻는 방법은 무엇입니까? (0) | 2020.11.09 |
Google App Engine의 장단점 (0) | 2020.11.09 |
Google Chrome 확장 (JavaScript + Chrome API)에서 웹 스크랩 핑 (0) | 2020.11.09 |