Ho provato node.js con mongodb (2.2.2) utilizzando l'unità node.js nativa di 10gen.Qual è il modo giusto per gestire le connessioni Mongodb?
All'inizio è andato tutto bene. Ma quando si arriva alla parte relativa al benchmarking della concorrenza, si sono verificati molti errori. Frequenti collegano/chiusura con 1000 convergenze possono causare mongodb respingere ogni ulteriore richiesta di errore del tipo:
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
Inoltre, se un sacco di clienti del sistema senza esplicito vicino, ci vorranno minuti mongodb per rilevare e chiuderli. Che causerà anche problemi di connessione simili. (Usando /var/log/mongodb/mongodb.log per verificare lo stato della connessione)
Ho provato molto. Secondo il manuale, mongodb non ha limiti di connessione, ma l'opzione poolSize sembra non avere effetti per me.
Come ho lavorato solo con il modulo nativo nodo-mongodb, non sono molto sicuro di cosa abbia causato il problema. Che dire delle prestazioni in altre lingue e driver?
PS: Attualmente, l'utilizzo del pool autogestito è l'unica soluzione che ho trovato, ma l'utilizzo non può non risolvere il problema con il set di repliche. Secondo il mio test, il set di repliche sembra richiedere molto meno connessioni quindi mongodb standalone. Ma non ho idea del perché questo accada.
codice di provaConcurrency:
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()
})
}
})
}
soluzione generica-pool:
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);
})
}
})
})
Anche se Node.js utilizza un unico processo e modello di eventi, ma le azioni IO deve essere sempre asincrona. Quale penso possa non essere la causa dei miei problemi. Ma, proverò nel modo in cui hai citato, grazie. – Jack
Ti manca il punto, nel tuo primo esempio; Quel codice equivale a far partire la tua app Mongo 1000 volte. Dovresti solo chiamare .connect una volta nella tua app. –
Sì, questo è un problema, e il motivo è che MongoClient mantiene un pool di connessioni stesso che diventa più costoso di altri dbs. Ma non il problema con il modello del singolo processo node.js. – Jack