2

昨夜のイベントの1つにライブティッカーを設定しましたが、深刻なパフォーマンスの問題が発生しました。Socket.ioは、400〜500を超えるクライアントが接続されているsocket.io.jsを提供できませんでした。ティッカーは非常にシンプルで、数分ごとに1つのメッセージがすべてのクライアントにブロードキャストされるため、コードに改善の余地はあまりないと思います。サーバーのハードウェアは最適ではありませんが、ティッカーの稼働時間中にプロセスを監視しており、いずれも問題を引き起こしていませんでした。

問題を解決する方法、または少なくとも他に何が原因である可能性があるかについて、何か考えがありますか。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
});
4

1 に答える 1

5

どのボトルネックにぶつかっているのかを判断するのは少し難しいです。あなたが探求するためのいくつかの可能性:

プロセスで開いているファイルハンドルの数の制限に達した可能性があります。Linuxカーネルは、プロセスごとに構成された最大ファイルハンドル数でコンパイルされます(ソケット接続はファイルハンドルを使用します)。「ulimit-a」を実行すると、(最大)オープンファイル制限を確認できます。あなたはあなたのプロセスを実行する前にこの数を増やすことができますちょうどグーグル「開いているファイルを制限する」。

別の考え...あなたはいつでも最大何通のメッセージを持っていますか?新しい接続ごとにこれらすべてを取得するためにdbクエリを実行しています。したがって、接続数が大幅に増加した場合は、最初のリストをロードするためだけにかなりの数のクエリを実行する可能性があります。実験として、スケーリングがどのように改善されるかを確認するために、最初の「接続」クエリを実行できませんでした。これが非常に役立つ場合は、接続ごとにデータベースにアクセスするのではなく、クエリ結果をjavascript変数に簡単にキャッシュできます。

いくつかの興味深い読書...

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

于 2012-11-25T13:25:30.137 に答える