您的位置:首页 > 理论基础 > 计算机网络

搜索系统17:HttpClient的网络连接是否被复用了

2017-11-11 16:29 507 查看
上文查看是否复用连接的方法有误,当时方法是把route(ip与端口等)传给连接池,相同的请求第二次就能返回相同的对象。这是没错,但相同的对象并不代表复用了Socket(连接)。因为这个对象是org.apache.http.pool.RouteSpecificPool。为了搞明白它与连接的关系,是否复用了连接,还需深入分析下。先查看一下它的结构:



一、从Socket到CPoolEntry的过程

1.Socket被绑定到一个ManagedHttpClientConnection:
代码位于:org.apache.http.impl.conn.HttpClientConnectionOperator



2.而这个ManagedHttpClientConnection正是CPoolEntry的构造参数。




上图里的构造参数是LoggingManagedHttpClientConnection,它是ManagedHttpClientConnection的子类。也就是说结构是这样的:Socket->ManagedHttpClientConnection->CpoolEntry。



二.怎么检测连接是否可用

从上面知道查看是否复用了CPoolEntry,就可以说明是否复用了连接。因为CPoolEntry是Socket产生的。

还是发送两次相同请求,查看第二次是否复用了上一次连接,发现关键代码在这里,org.apache.http.impl.execchain.MainClientExec。在第二次请求时会判断这个连接是否关闭。



再进去看一下怎么判断这个连接是不可用的:



如图,从输入流读点数据。如果返回-1,没读到数据,就认为不可用,就要关闭了。这种情况一般是服务器关闭了。后面我测试不同httpClient发现,检测方法并不一样,4.3.3是这样的,4.5.3并不用这个方法。

三、编写测试是否复用方法

1.准备环境。

新建一个maven项目。引入httpclient 4.5.3。找到对象的源码包httpclient-4.5.3-sources.jar与httpcore-4.4.6-sources.jar,解压把源码放进本项目。再引入以下两个包



2.修改源码

在org.apache.http.impl.conn.PoolingHttpClientConnectionManager增加以下一句打印日志:



3.编写测试代码

使用同一个HttpClient对象,两次请求同一个HttpGet对象(url)。分两组,1组间隔20秒,1组间隔120秒。可以发现第二次返回的对象不一样,如下图:



有时候我们设置了超时、keepAlive等参数,但还是不知道到底服务器是否复用了连接,复用的有效期是多久。就可以通过这个方法来测试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: