NodeJs性能问题

我正在使用NodeJs构build一个实时统计应用程序。 对于原型,我在RackSpace服务器中使用了AMD Opteron四核处理器,使用Cluster NodeJs( http://learnboost.github.com/cluster/ )和使用本地nodejs驱动程序的MongoDb对nodejs服务器进行testing。

基本上我已经在我的公司项目中插入了一个JS代码,为一些客户的网站提供内容。 这段代码每隔10秒钟就会“ping”我的服务器,调用一个图像并传递我在服务器端获得的参数,并在MongoDb集合中插入(或更新)参数。 在一天的“慢”时间里,我每次获得大约3000个连接(我在terminal上使用netstat -natp命令获得这些连接),使得我的集群每个核心使用大约25%(我使用“top”命令)。 但是在一个“忙碌”的时候,每次我的集群变得疯狂(每个核心使用大约80%),每次得到大约7000多个连接,而且随着时间的推移,节点退化。 这是正常的吗? 还是应该Nodejs处理这些命中更“容易”的方式? 如果我使用mongoose,性能会增加吗?

如果你对MongoDb很好奇的话,它占用了一个核心的4%,这对我来说是很好的(没有把索引用于大约50%以上,但是至less索引解决了这个性能问题)。

干劲十分感谢,干杯。

编辑:

使插入的代码如下所示: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'); }); }); 

这是正常的吗?

取决于他们自己的联系吗? 他们只是继续build设吗? 你在谈论“networking连接”(http)还是MongoDB连接?

mongod日志说什么? node日志说什么?

你每秒收到多less个请求?

还是应该Nodejs处理这些命中更“容易”的方式?

很难说不知道代码在做什么。

你希望盒子能同时处理多less个连接?

如果我使用mongoose,性能会增加吗?

所以Mongoose实际上是node-mongodb-native驱动程序的对象封装。 这不是一个不同的驱动程序,它只是一个包装。

包装器将代码添加到您已有的代码中。 如果您有代码问题,那么添加代码并不能保证使问题更好。 如果mongoose确实解决了你的问题,那么它正在做一些你没有的连接。 如果那样的话,你不一定需要mongoose,你只需要更好的连接pipe理。


看看你的问题有很多潜在的来源。

解决这个问题的唯一方法就是打破这些部分,然后再深入挖掘。 开始的地方: – 连接到MongoDB正确closures(查看数据库日志)? – 日志中是否包含其他错误? – 为节点日志做同样的事情? – 你有关于内存使用情况的图表吗? 谁占用了最多的内存? – 当你达到每个核心的80%时,哪个过程是这样做的? mongodnode ? 别的东西?

为了真正帮助你,我们需要更多关于系统发生了什么的数据。

持续的请求可能会相当昂贵,特别是如果它们之间的超时很小。 在你的情况下,你正在接受约300-700 +并发请求每秒和你的系统负载可以取决于你在处理什么。 您可以尝试切换到Mongoose,但是我宁愿看image processing和caching,如果它适用于您的scheme,因为数据库似乎不是你的瓶颈(虽然DB驱动程序也可能是问题)。

 if (!transparent) { console.log('!transparent'); transparent = fs.readFileSync(__dirname + '/../../public/images/transparent.gif', 'binary'); } 

透明度多久是错误的? 我没有看到它在代码中定义。 您正在阻止同步磁盘IO上的整个节点进程,可能是针对每个请求。 为什么? 如果您必须从磁盘读取文件,请asynchronous执行。 如果文件是静态的和小的,也许你应该把它加载到内存中一次。

节点的http服务器默认保持活动状态。 它会导致你的情况下太多无用的连接。 只要尝试添加一个头来disable Keep-Alive – 与群集平原节点将罚款。

 res.setHeader("Connection", "close") 

只是一个更新:

我已经放弃了集群并在服务器上放置了一个Nginx层。 所以花了很多时间去“降级”,但仍然是这样做的,特别是消耗了大量的系统RAM内存。 有什么想法吗?

并且非常感谢所有的答案!

编辑:重新做了一些testing。 我认为主要问题是关于开放的联系。 当我在Nginx端口上运行一个netstat时,它说2000连接。 当我在每个nodejs应用程序端口上运行它说2000(或更多)。 基本上我的“最好的情况下”将是nodejs应用程序打开连接的总和将匹配Nginx端口上的打开连接,对不对? 我认为这是主要的问题,它影响了巨大的“时间等待”状态。

你也许只想从缓冲区提供这个透明的gif,就像在这里做的那样:

https://gist.github.com/657246#comments