10gen이 기본 node.js 드라이브를 사용하여 mongodb (2.2.2)와 함께 node.js를 시도합니다.Mongodb 연결을 처리하는 올바른 방법은 무엇입니까?
처음에는 모든 것이 잘되었습니다. 그러나 동시성 벤치마킹 부분에 오면 많은 오류가 발생합니다. 자주 연결/닫기 1000 concurrencies에 발생할 수 MongoDB의 오류 등으로 더 이상의 요청을 거부 :
Error: failed to connect to [localhost:27017]
Error: Could not locate any valid servers in initial seed list
Error: no primary server found in set
또한, 명시 적으로 가까운없이 클라이언트 종료를 많이, 그것은 감지하고 그들을 닫습니다 MongoDB를 분 정도 걸릴 수 있습니다 경우. 비슷한 연결 문제가 발생할 수도 있습니다. (/var/log/mongodb/mongodb.log를 사용하여 연결 상태를 확인하십시오.)
나는 많은 시도를했습니다. 매뉴얼에 따르면 mongodb에는 연결 제한이 없지만 poolSize 옵션은 나에게 아무런 영향을 미치지 않는 것으로 보입니다.
node-mongodb-native 모듈에서만 작업 했으므로 결국 어떤 문제가 발생했는지 잘 모르겠습니다. 다른 언어 및 드라이버의 성능은 어떻습니까?
추신 : 현재, 자체 유지 관리 된 풀만 사용하면 알아 낸 유일한 해결책이지만 사용하면 복제본 세트로 문제를 해결할 수 없습니다. 내 테스트에 따르면 복제본 세트는 독립형 mongodb보다 훨씬 적은 연결로 보인다. 그러나 이것이 왜 발생하는지 전혀 모릅니다.
동시성 테스트 코드 :
var MongoClient = require('mongodb').MongoClient;
var uri = "mongodb://192.168.0.123:27017,192.168.0.124:27017/test";
for (var i = 0; i < 1000; i++) {
MongoClient.connect(uri, {
server: {
socketOptions: {
connectTimeoutMS: 3000
}
},
}, function (err, db) {
if (err) {
console.log('error: ', err);
} else {
var col = db.collection('test');
col.insert({abc:1}, function (err, result) {
if (err) {
console.log('insert error: ', err);
} else {
console.log('success: ', result);
}
db.close()
})
}
})
}
일반 풀 솔루션 :
Node.js를 이후var MongoClient = require('mongodb').MongoClient;
var poolModule = require('generic-pool');
var uri = "mongodb://localhost/test";
var read_pool = poolModule.Pool({
name : 'redis_offer_payment_reader',
create : function(callback) {
MongoClient.connect(uri, {}, function (err, db) {
if (err) {
callback(err);
} else {
callback(null, db);
}
});
},
destroy : function(client) { client.close(); },
max : 400,
// optional. if you set this, make sure to drain() (see step 3)
min : 200,
// specifies how long a resource can stay idle in pool before being removed
idleTimeoutMillis : 30000,
// if true, logs via console.log - can also be a function
log : false
});
var size = [];
for (var i = 0; i < 100000; i++) {
size.push(i);
}
size.forEach(function() {
read_pool.acquire(function (err, db) {
if (err) {
console.log('error: ', err);
} else {
var col = db.collection('test');
col.insert({abc:1}, function (err, result) {
if (err) {
console.log('insert error: ', err);
} else {
//console.log('success: ', result);
}
read_pool.release(db);
})
}
})
})
Node.js를가 단일 프로세스 및 이벤트 모델을 사용하지만 IO 작업은 항상 비동기해야하지만. 나는 내 이슈의 원인이 아닐지도 모른다. 하지만, 내가 인용 한대로 해보겠습니다. 고마워요. – Jack
첫 번째 예에서는 요점을 놓치고 있습니다. 이 코드는 Mongo 앱을 1000 번 시작하는 것과 같습니다. 앱에서 한 번만 .connect를 호출해야합니다. –
네, 그게 문제입니다. 그 이유는 MongoClient가 다른 dbs보다 비용이 많이 드는 연결 풀을 보유하고 있기 때문입니다. 하지만 node.js 단일 프로세스 모델의 문제는 아닙니다. – Jack