nodejs中http连接池复用的问题

nodejs中对于http的request调用,默认会使用globalAgent,这个对象默认创建五个连接池。为了证明这个观点,首先编写如下测试代码:

var testhttp = require('../testhttp');
var count = 0;
for(var i= 0;i<1000;i++) {
        testhttp.getOriginal('http://www.baidu.com',function(err,body) {
            console.log(count++, err);
        });
}

代码1 test_get_baidu3_nowait.js
为了测试方便,专门修改了百度域名(wwww.baidu.com)的hosts定义,在操作系统的hosts文件中专门添加这么一行:

61.135.169.125        www.baidu.com

当然这里的ip需要你自己先ping一下www.baidu.com,将其改为ping出来的域名,如果你不这么做的话,百度的cdn会不时的切换ip,因为我们下边要用到wireshark,需要一个固定的ip。
接着打开wireshark,在捕获选项界面中填入:

host 61.135.169.125 and port 80

《nodejs中http连接池复用的问题》
确定之后,在主界面中填入过滤条件:

tcp.flags.syn==1 && ip.src==192.168.1.3

《nodejs中http连接池复用的问题》
因为这里只关心连接建立。点击应用,然后运行test_get_baidu3_nowait.js.
会发现整个过程一共只有5次tcp握手请求(确切的说应该稍微会多余5次,因为当中要考虑到http服务器会强制断开tcp连接的情况,这个时候就逼迫客户端重新做tcp连接,所以说tcp连接请求可能要这么6、7次的样子)。
接下来问题来了,假设我们在异步回调中再调用http请求,就会发现每个请求都会建立tcp连接,下面是我们的代码:

var testhttp = require('../testhttp');
var count = 0;
for(var i= 0;i<1000;i++) {
    setTimeout(function() {
        testhttp.getOriginal('http://www.baidu.com',function(err,body) {
            console.log(count++, err);
        });
    },100*i);
}

代码2 test_get_baidu3.js
会发现连接建立的大概有10多次,起初以为是异步回掉时,自带的连接池有问题,后来仔细观察了一下还是服务器端强制断开连接造成了,每次强制断开连接一次,客户端就会创建一个新的连接放到池子中去。
试着将setTimeout的时间间隔改为0,发现连接建立次数跟代码1相比差不多了。看来服务器端对于连接的活跃程序很敏感,稍微一超时就会被干掉。
项目中用到的代码,可以从http://git.oschina.net/yunnysunny/benchmark-http-request-node 获取。

    原文作者:白一梓
    原文地址: https://segmentfault.com/a/1190000002924891
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞