Я создаю приложение статистики в реальном времени, используя NodeJs. В качестве прототипа я использую четырехъядерный процессор AMD Opteron на сервере RackSpace для теста с сервером nodejs с использованием NodeJs кластера (http://learnboost.github.com/cluster/) и MongoDb с использованием собственного драйвера nodejs.
По сути, я вставил код JS в проект моей компании, который доставляет контент для нескольких веб-сайтов клиентов. Этот код «пингует» мой сервер каждые 10 секунд, вызывая изображение и передавая параметры, которые я получаю на стороне сервера и вставляю (или обновляю) в коллекцию MongoDb. В «медленное» время дня я получаю около 3000 соединений (я получаю их с помощью команды netstat -natp на терминале) каждый раз, когда мой кластер использует около 25% каждого ядра (я получаю их с помощью команды «top»). ). Но в «напряженный» час я получаю около 7000+ соединений каждый раз, что сводит мой кластер с ума (около 80% + использование каждого ядра), и кажется, что со временем узел ухудшается.
Это нормально? Или Nodejs должен обрабатывать эти попадания более «легким» способом? Если я использую Mongoose, производительность может увеличиться?
В случае, если вам интересно, что MongoDb использует около 4% одного ядра, это хорошо для меня (без указания индекса использование составляло около 50% +, но, по крайней мере, индекс решил эту проблему с производительностью).
Большое спасибо за терпение,
Приветствия.
Edit:
Код, который делает вставку, выглядит следующим образом:
db.open (function (err, db) {});
return connect.router(function(app){
app.get("/pingserver/:clientid/:event/:cachecontrol", function(req, res, next){
event:'+req.params.event + ', cachecontrol:' + req.params.cachecontrol);
var timestamp = new Date();
switch(req.params.event) {
case 'load':
var params = url.parse(req.url, true).query;
db.collection('clientsessions', function(err, collection) {
try {
var client = {
id: req.params.clientid,
state: req.params.event + 'ed',
loadTime: timestamp.getTime(),
lastEvent: req.params.event,
lastEventTime: timestamp.getTime(),
lastEventDate: timestamp.toString(),
events: [{
event: req.params.event,
timestamp: timestamp.getTime(),
date: timestamp.toString()
}],
media: {
id: params.media.split('|')[0] || null,
title: unescape(params.media.split('|')[1]) || null
},
project: {
id: params.project.split('|')[0] || null,
name: unescape(params.project.split('|')[1]) || null
},
origin: req.headers['referer'] || req.headers['referrer'] || '',
userAgent: req.headers['user-agent'] || null,
userIp: req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress)),
returningUser: false
};
}catch(e) {console.log(e);}
collection.insert(client, function(err, doc) {
});
});
break;
case 'ping':
db.collection('clientsessions', function(err, collection) {
collection.update({id: req.params.clientid}, {
$set : { lastEvent: req.params.event
,lastEventTime: timestamp.getTime(),lastEventDate: timestamp.toString()}
}, {}, function(err, doc) {});
});
break;
default:
db.collection('clientsessions', function(err, collection) {
collection.update({id: req.params.clientid}, {
$set : {state: req.params.event+'ed'
, lastEvent: req.params.event
, lastEventTime: timestamp.getTime()}
, $push : { events : { event: req.params.event, timestamp: timestamp.getTime(), date: timestamp.toString() } } }, {}, function(err, doc) {});
});
break;
}
if (!transparent) {
console.log('!transparent');
transparent = fs.readFileSync(__dirname + '/../../public/images/transparent.gif', 'binary');
}
res.setHeader('Content-Type', 'image/gif');
res.setHeader('Content-Length', transparent.length);
res.end(transparent, 'binary');
});
});