【译】Node.js的速度困境:AJAX 和 Socket.IO到底选哪一个?

翻译:疯狂的技术宅
原文标题:A Node.js speed dilemma: AJAX or Socket.IO?
原文连接:http://www.cubrid.org/blog/no...
本文首发微信公众号:充实的脑洞。转载需注明出处!javascript

当我开始本身的第一个Node.js项目时,我发现的第一件事就是如何处理浏览器(客户端)和中间件之间的通讯(中间件是用CUBRID Node.js驱动编写的(node-cubrid)的Node.js应用与CUBRID 8.4.1数据库交换信息)。html

我已经很是熟悉AJAX了,可是在学习Node.js时,我发现了Socket.IO模块,甚至在互联网上发现了一些很是不错的代码示例... 很是好用(重用)...java

所以,这很快成为一个难题:应该选哪一个,Ajax仍是sockets.io?node

显然,因为个人经验很是有限,因此我须要更多的信息。换句话说,应该好好的Google一番 :)jquery

显然相关的信息很是多,可是须要过滤掉那些没用的 "噪音",并获得真正有用的东西。让我跟你们分享一下关于这个话题的一些连接:web

总而言之,这是我发现的:

  1. Socket.IO(一般)用的是客户端和服务器(中间件)之间的持续链接,所以你会达到服务器端资源所容许的并发链接数上限(而相同的资源能够支持更多的AJAX异步请求)。

  2. 使用AJAX,你能够请求RESTful接口。这意味着您能够利用现有的 HTTP 服务,例如:代理缓存请求和带条件的GET请求。

  3. 与 Socket.IO 相比,AJAX 有更多(通讯)数据开销(例如:HTTP头,Cookie等)。

  4. AJAX一般比Socket.IO快 ...

  5. 当使用Socket.IO时,能够进行双向通讯,其中每一方——客户端或服务器均可以发起请求。在AJAX中,只有客户才能发起请求!

  6. Socket.IO有更多的传输选项,包括Adobe Flash。

如今,对于我本身的应用,我最感兴趣的是发起请求并从(Node.js)服务器获取数据的速度!

关于与CUBRID数据库中间件的数据通讯,由于大约90%的数据访问是只读的,一个好的数据缓存机制显然是一个不错的途径!但关于这个,我下次再谈。

因此我决定对他们的(Ajax和socket)速度进行测试,看看哪个更快(至少在个人硬件和软件环境下)!个人硬件环境是:i5处理器,8GB内存和英特尔X25 SSD硬盘。

可是严格来讲,任何性能测试都取决于您的硬件和软件配置,在你本身的环境中去测试终归是一个好主意,不要过于依赖你在互联网上找到的各类信息,更多的问题须要你本身去发现!

我要作的测试须要知足如下要求:

  • 测试:

    • AJAX

    • Socket.IO 持续链接模式

    • Socket.IO 非持续连接模式

  • 测试客户端与服务器之间进行十、100,、250、500条数据交换时的状况

  • 中间件服务器(Node.js Web 服务器)和客户端(浏览器)之间交换的每条数据都是一个4KBytes的随机数据串

  • 在 release(非调试)模式下运行服务器

  • 用Firefox做为客户端

  • 最小化控制台消息输出,不论是服务器端仍是客户端

  • 在客户端页面硬性从新加载后进行每一个测试

  • 每次测试至少重复3次,以确保结果一致

测试Socket.IO,使用持久链接

我建立了一小型的小Node.js服务器,用它处理客户端请求:

io.sockets.on('connection', function (client) {
    client.on('send_me_data', function (idx) {
        client.emit('you_have_data', idx, random_string(4096));
    });
});

这是我用于测试的JS客户端脚本:

var socket = io.connect(document.location.href);
 
socket.on('you_have_data', function (idx, data) {
    var end_time = new Date();
    total_time += end_time - start_time;
    logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.');
    if (idx++ < countMax) {
        setTimeout(function () {
            start_time = new Date();
            socket.emit('send_me_data', idx);
        }, 500);
    }
});

测试Socket.IO,使用非持久链接

此次,对于每次数据交换,我都打开一个新的socket-io链接。

Node.js服务器代码与上一个相似,可是我决定在链接以后当即发送客户端数据,由于每次数据交换都会启动一个新的链接:

io.sockets.on('connection', function (client) {
    client.emit('you_have_data', random_string(4096));
});

客户端测试代码:

function exchange(idx) {
    var start_time = new Date();
    var socket = io.connect(document.location.href, {'force new connection' : true});
 
    socket.on('you_have_data', function (data) {
        var end_time = new Date();
        total_time += end_time - start_time;
        socket.removeAllListeners();
        socket.disconnect();
        logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.');
         
        if (idx++ < countMax) {
            setTimeout(function () {
                exchange(idx);
            }, 500);
        }
    });
}

测试AJAX

最后是AJAX测试...

Node.js服务器代码与之前的代码不一样:

res.writeHead(200, {'Content-Type' : 'text/plain'});
res.end('_testcb(\'{"message": "' + random_string(4096) + '"}\')');

至于客户端代码,这是我之前测试的:

function exchange(idx) {
    var start_time = new Date();
 
    $.ajax({
        url : 'http://localhost:8080/',
        dataType : "jsonp",
        jsonpCallback : "_testcb",
        timeout : 300,
        success : function (data) {
            var end_time = new Date();
            total_time += end_time - start_time;
            logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.');
             
            if (idx++ < countMax) {
                setTimeout(function () {
                    exchange(idx);
                }, 500);
            }
        },
        error : function (jqXHR, textStatus, errorThrown) {
            alert('Error: ' + textStatus + " " + errorThrown);
        }
    });
}

记住,当将AJAX和Node.js一块儿编码时,你须要考虑到可能的跨域请求和同源策略,所以应该使用基于JSONP的格式!

顺便说一句,能够看到,我仅引用了测试代码中最重要的部分,以节省篇幅。若是有人须要完整的服务器和客户端代码,请告诉我 - 我很乐意分享。

好的 - 如今看看完成这些工做后咱们获得了什么!

我分别运行了十、100、250和500个数据交换的测试,这是最终测试结果:

Data exchanges Socket.IO NON-persistent (ms.) AJAX (ms.) Socket.IO persistent (ms.)
10 90 40 32
100 900 320 340
250 2,400 800 830
500 4,900 1,500 1,600

看看结果,咱们会注意一些状况:

  1. 对于每种类型的测试,结果遵循线性增加的规律,这很好——代表结果是一致的。

  2. 结果清楚地代表,当使用Socket.IO非持久性链接时,性能数字比其余数据差得多。

  3. 在AJAX和Socket.IO持久链接之间彷佛并无太大区别——咱们只谈几毫秒的差别。 这意味着,若是您天天的数据交换次数不超过10,000次的话,用户基本上不会注意到速度差别...

下图描述了在测试中得到的数字:

那么接下来呢?

嗯,我必须弄清楚本身须要支持什么样的流量,而后我将从新运行这些测试,但此次不包括Socket.IO非持久链接。由于很明显,我须要在AJAX和持久的Socket.IO链接之间进行选择。

并且我也了解到,最有可能的是,速度差别不会像人们想象的那样大,至少不是为了一个“小流量”的网站,因此我在肯定本身的解决方案时,还须要研究每一个方法/技术的其余优缺点!

  1. 这里有一些资源,能够找到关于Node.js、Socket.IO 和 AJAX 的一些有趣的东西:

关注微信公众号:充实的脑洞, 一个技术宅的保留地
相关文章
相关标签/搜索