1000连接上100%的CPU使用率 – Node.js,socket.io,集群和Redis …

我的聊天工作在24个线程(2个6核心X5650 @ 2.67GHz)…如果有大约1000个连接CPU使用率(每个线程)增长到80-100%….我认为有什么是我的错代码…节点不应该只有1000个连接产生这样的负载。 你可以给我一些关于在哪里看的想法

我的代码:

express = require('express') http = require('http'); cluster = require("cluster"); numCPUs = require("os").cpus().length, port = 55678; userCount = 0; interv = false; RedisStore = require("socket.io/lib/stores/redis"), redis = require("socket.io/node_modules/redis"), pub = redis.createClient(), sub = redis.createClient(), client = redis.createClient(), counter = redis.createClient(); counter.set('count',0); client.set('searching',0); client.del('freeusers'); if (cluster.isMaster) { for (var i = 0; i < numCPUs; i++) { cluster.fork(); } } else { app = express(); server = http.createServer(app).listen(port); io = require('socket.io').listen(server); io.configure(function () { // io.set("transports", ["websocket"]) io.set("store", new RedisStore({ redisPub: pub, redisSub: sub, redisClient: client }) ); io.set('log level', 0); io.enable('browser client minification'); io.enable('browser client etag'); io.enable('browser client gzip'); }); app.get('/', function (req, res) { res.sendfile(__dirname + '/index.php'); }); io.sockets.on('connection', function (socket){ var address = socket.handshake.address; socket.set('options', JSON.stringify({'sex':'male','seek':'both'})); socket.set('partner', 5); socket.set('ip', address.address); socket.emit('setsocket',socket.id); counter.incr('count', function(err, newId){ userCount = newId; socket.emit('people', userCount); socket.broadcast.emit('people', userCount); // console.log(Date(Date.now()) + ' Connected User ('+socket.id+' | '+address.address+':'+address.port+') '+userCount); }); socket.ip = address.address; socket.on('syscmd', function(cmd){ switch (cmd.cmd){ case 'new': socket.set('options', JSON.stringify({'sex':cmd.sex,'seek':cmd.seek})); socket.emit('updatechat', 'Poszukujemy dla Ciebie obcego, poczekaj ...'); socket.emit('setflag',1); addNewUser(socket.id); lookforpartner(socket.id); break; case 'reconnect': socket.set('options', JSON.stringify({'sex':cmd.sex,'seek':cmd.seek})); socket.get('partner', function(err, partner){ stopchat(socket.id,partner); socket.emit('updatechat', 'Poszukujemy dla Ciebie obcego, poczekaj ...'); socket.emit('setflag',1); addNewUser(socket.id); lookforpartner(socket.id); }); break; default: } }); socket.on('sexchange', function (sex) { socket.get('options',function(err,options){ socket.set('options', JSON.stringify({'sex':sex,'seek':options.seek})); }); }); socket.on('seekchange', function (seek) { socket.get('options',function(err,options){ socket.set('options', JSON.stringify({'sex':options.sex,'seek':seek})); }); }); socket.on('updatechat', function(data){ socket.get('partner', function(err, partner) { io.sockets.socket(partner).emit('updatechat',data); }); socket.emit('updatechat',data); }); socket.on('msgchat', function (data) { socket.get('partner', function(err, partner) { io.sockets.socket(partner).emit('msgchat',socket.id,data); // console.log('Message between: '+socket.id+ ' AND '+partner+': '+data); }); socket.emit('msgchat',socket.id , data); }); socket.on('typing', function (data) { socket.get('partner', function(err, partner){ io.sockets.socket(partner).emit('typing'); }); }); socket.on('stoptyping', function (data) { socket.get('partner', function(err, partner){ io.sockets.socket(partner).emit('stoptyping'); }); }); socket.on('disconnect', function(){ var address = socket.handshake.address; socket.get('partner', function(err, partner){ stopchat(socket.id,partner) counter.decr('count', function(err, newId){ userCount = newId; socket.broadcast.emit('people', userCount); // console.log(Date(Date.now()) + ' Disconnected User ('+socket.id+' | '+address.address+':'+address.port+') '+userCount); }); }); }); function removeUser(id) { client.srem('freeusers',id); } function addNewUser(id) { removeUser(id); client.sadd('freeusers',id); } function lookforpartner(id) { // console.log('('+id+') searching ...') client.get('searching',function(error,result){ if(parseInt(result) == 1) { return true; } else { client.smembers('freeusers',function(error,freeusers){ if(freeusers.length > 1) { client.set('searching',1); partner = freeusers[Math.floor(Math.random()*freeusers.length)]; while(partner == id) { partner = freeusers[Math.floor(Math.random()*freeusers.length)]; } socket.get('options',function(err,options){ options = JSON.parse(options); if(err || options == null || typeof options != 'object' || !options.hasOwnProperty('seek') || !options.hasOwnProperty('sex')) { client.set('searching',0); return false; } // console.log('partner: '+id+' (sex:'+options.sex+' and seek:'+options.seek+')'); io.sockets.socket(partner).get('options',function(err,poptions){ poptions = JSON.parse(poptions); if(err || options == null || typeof poptions != 'object' || !poptions.hasOwnProperty('seek') || !poptions.hasOwnProperty('sex')) { removeGhost(partner); client.set('searching',0); return false; } // console.log('partner: '+partner+' (sex:'+poptions.sex+' and seek:'+poptions.seek+')'); if((options.seek == poptions.sex || options.seek == 'both') && (poptions.seek == options.sex || poptions.seek == 'both')) { // console.log('parred: '+partner+' (sex:'+poptions.sex+' and seek:'+poptions.seek+') AND '+id+' (sex:'+options.sex+' and seek:'+options.seek+')'); removeUser(partner); removeUser(id); io.sockets.socket(id).set('partner', partner); io.sockets.socket(partner).set('partner', id); io.sockets.socket(id).emit('chatunblock',1); io.sockets.socket(partner).emit('chatunblock',1); io.sockets.socket(id).emit('updatechat', 'Obcy podłączony, napisz Cześć :-)'); io.sockets.socket(partner).emit('updatechat', 'Obcy podłączony, napisz Cześć :-)'); } client.set('searching',0); }); }); } }); } }); } function removeGhost(id) { console.log('Removing ghost: '+id); removeUser(id); io.sockets.socket(id).set('partner', 5); io.sockets.socket(id).emit('disconnected','end'); } function stopchat(id,partner) { removeUser(id); if(partner != 5) { socket.set('partner', 5); io.sockets.socket(partner).set('partner', 5); io.sockets.socket(partner).emit('updatechat', 'Obcy wyszedł :-('); io.sockets.socket(partner).emit('disconnected','end'); } io.sockets.socket(id).emit('disconnected',2); } }); }