一.HttpClient请求的一般过程

1.拿连接

1.jpg

2.与服务器建立连接(new Socket)

2.jpg

3.从服务获取结果

3.jpg

4.keepAlive的判断

在代码org.apache.http.impl.execchain.MainClientExec里请求结束后(requestExecutor.execute),用策略模式来判断是否keepAlive

if (reuseStrategy.keepAlive(response, context))

从以下实现可以看出,keepAlive的标志是从Response的Header中取得的

4.jpg

还有最后一句,如果header里没有,http版本号大于1.0,也会保持连接。

如果没有keepAlive那么就会执行connHolder.markNonReusable,这个就是把ConnectHolder的reusable置为false。不过我测试了很多的网站,都返回了Keep-Alive,应该都可以保持连接一段时间。

5.归还连接

在ConnectionHolder类里可以看到以下代码:

5.jpg

如果reusable=false,也就是没有keepalive,就会关闭连接。

二、http请求头的格式怎么获取?

以访问https://www.baidu.com为例:

在代码org.apache.http.impl.io.SessionOutputBufferImpl.flushBuffer方法内打断点

1.jpg

三、连接是否被连接池复用了?

连续两次请求同一个地址,在代码AbstractConnPool.AbstractConnPool.getPool里查看第三次执行情况,直接从连接池里取出了对象则被复用了,否则没有。这里被复用了并不意味着能执行成功,还要看服务器是否关闭了连接。为什么是第三次,因为一次请求会在leaseConnection和releaseConnection调用这个getPool方法,共两次,所以第二次请求是第三次。

1.jpg

再看一下这个HttpRoute对象的hashcode方法,恩,就是这些因素决定了是不是同一个请求。