Socket.io性能问题

时间:2012-11-24 10:32:06

标签: performance node.js socket.io

我们昨晚为我们的一个活动设置了一个实时自动收报机,我们遇到了严重的性能问题。 Socket.io无法为连接超过400到500个客户端的socket.io.js提供服务。自动收报机非常简单,每隔几分钟只有一条消息被广播给所有客户,因此我认为代码中没有太大的改进空间。服务器的硬件不是最好的,但我们在自动收报机正常运行期间监控这些流程,但没有一个导致问题。

您是否知道如何解决问题或者至少还有其他原因可以解决问题。看起来socket.io只是在苦苦挣扎,但不是因为缺乏硬件能力。

服务器结构

var io = require('socket.io').listen(443);
io.set('log level', 9);

//SQL CONNECTION

io.sockets.on('connection', function (socket) {

var sql_items = 'SELECT * FROM entries ORDER BY tstamp DESC';

db_query(sql_items , function(res_items) {
    socket.emit('init', res_items);
});    
socket.on('new_entry', function (data) {
        //SECURE
    if(!checkedSocketUsers[socket.id]) return false;

    var currentTime = new Date();

    if(currentTime.getMinutes() < 10);

    var minutes = currentTime.getMinutes();
    if(minutes < 10) minutes = "0" + minutes;

    var hours = currentTime.getHours();
    if(hours < 10) hours = "0" + hours;

    var tstamp = currentTime.getTime() / 1000;

    var time = hours + ":" + minutes;

    sqli = "INSERT INTO entries (uid, tstamp, text, type) VALUES (null, "+tstamp+", '"+data.text+"', '"+data.type+"')"; 
    client.query(sqli, function(err, info) {

        var br_data = {};

        br_data.time = time;
        br_data.text = data.text;
        br_data.uid = info.insertId;
        br_data.type = data.type;

        socket.broadcast.emit('broadcast_entry', br_data);
        socket.emit('broadcast_entry', br_data);
    });
});

socket.on('update_entry', function(data) {
    //SECURE
    if(!checkedSocketUsers[socket.id]) return false;

    sqlu = "UPDATE entries SET text = '"+data.text+"' WHERE uid = "+data.uid;   

    client.query(sqlu, function(err, info) {

        br_data = data;

        socket.broadcast.emit('broadcast_update_entry', br_data);
    });
});

socket.on('remove_entry', function(data) {
    //SECURE
    if(!checkedSocketUsers[socket.id]) return false;

    var uid = data.uid;

    sqld = "DELETE FROM entries WHERE uid = "+uid;  
    client.query(sqld, function(err, info) {
        var br_data = {};

        br_data.uid = uid;

        socket.broadcast.emit('broadcast_remove_entry', br_data);
        socket.emit('broadcast_remove_entry', br_data);
    });
});
});

客户端结构

socket = io.connect("http://localhost:443");    

socket.on('init', function(data) {
//DOM Manipulation
});

socket.on('broadcast_entry', function(data) {
//DOM Manipulation
});

socket.on('broadcast_remove_entry', function(data) {
//DOM Manipulation
});

socket.on('broadcast_update_entry', function(data) {
//DOM Manipulation
});

1 个答案:

答案 0 :(得分:4)

说出你遇到的瓶颈有点难。您可以探索几种可能性:

您可能已达到流程中打开文件句柄数量的限制。您的Linux内核使用每个进程配置的最大文件句柄数进行编译(套接字连接使用文件句柄。)您可以通过运行&#34; ulimit -a&#34;来查看(max)打开文件限制。您可以在运行流程之前增加此号码,只需谷歌&#34; ulimit打开文件&#34;。

另一个想法......在任何给定时间你有多少条消息?您正在执行数据库查询以检索每个新连接的所有这些。因此,如果连接数量急剧增加,您可能只是为了加载初始列表而进行了大量查询。作为一个实验,你不能做初始的&#34;连接&#34;查询以查看缩放如何改进。如果这有很大帮助,那么您可以轻松地将查询结果缓存在javascript变量中,而不是为每个连接访问数据库。

一些有趣的阅读......

http://drewww.github.com/socket.io-benchmarking/