我正在使用 NodeJs 构建一个实时统计应用程序。对于原型,我在 RackSpace 服务器中使用四核 AMD Opteron 来测试使用 Cluster NodeJs ( http://learnboost.github.com/cluster/ ) 的 nodejs 服务器和使用本机 nodejs 驱动程序的 MongoDb .
基本上,我在我的公司项目中插入了一个 JS 代码,它为一堆客户的网站提供内容。此代码每 10 秒“ping”一次我的服务器,调用图像并传递我在服务器端获取并在 MongoDb 集合中插入(或更新)的参数。在一天中的“慢”时间里,我每次获得大约 3000 个连接(我使用终端上的 netstat -natp 命令获得这些连接),这使我的集群使用每个核心的大约 25%(我使用“top”命令获得这些连接) )。但是在“忙碌”的时间里,我每次都会获得大约 7000 多个连接,这让我的集群变得疯狂(每个核心的使用率大约 80% 以上),而且似乎随着时间的推移,节点会降级。这是正常的吗?还是 Nodejs 应该以更“简单”的方式处理这些命中?如果我使用Mongoose,性能可以提高吗?
如果您对 MongoDb 感到好奇,它使用了大约 4% 的一个内核,这对我来说很好(没有放置索引,使用率约为 50%+,但至少,索引解决了这个性能问题)。
非常感谢您的耐心,干杯。
编辑:
进行插入的代码如下所示: 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');
});
});