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

时间:2013-07-17 14:47:15

标签: node.js redis socket.io cluster-computing

我的聊天工作在24个线程(2x 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);
        }

    });

}

0 个答案:

没有答案