http连接重用
从一个主机向另外一个建立连接的过程时相当复杂的,而且包含了两个终端之间的很多包的交换,它是相当费时的。
连接握手的开销是很重要的,特别是对小量的HTTP报文。
如果打开的连接被重用来执行多次请求,那么就可以达到很高的数据吞吐量
持久性连接
http1.1强调的http连接默认情况可以被重用于多次请求
http1.0兼容的终端也可以使用相似的机制来明确的交流它们的偏好来保证连接处于活动状态,使用它来处理多个请求
http请求也可以保持空闲连接处于一段时间的活动状态,防止对相同目标主机的后续的请求。
保持连接活动的能力称为持久性连接
httpclient完全支持持久性连接
连接存活策略
HTTP规范没有规定一个持久连接应该存活多久,有些http服务器使用非标准的Keep-Alive头消息和客户端进行交互,服务器端会在数秒时间内保持连接。
HttpClient也会利用这个头消息,如果服务器返回的响应中没有包含Keep-Alive头消息,HttpClient会认为这个连接可以永远保持。
然后,很多服务器都会在不通知客户端的情况下,关闭一定时间内部活动的连接,来节省服务器资源。
在某些情况下默认的策略显得太乐观,我们可能需要自定义连接存活策略。
连接保持活跃策略
ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
public long getKeepAliveDuration(HttpResponse response ,HttpContext context){
//honor 'keep-alive' header 兑现'keep-alive头部信息'
HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while(it.hasNext()){
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if(value!=null && param.equalsIgnoreCase("timeout")){
try{
return Long.parseLong(value)*1000;
}catch(NumberFormatException e){
//转换错误
}
}
}
HttpHost host = (HttpHost) context.getAttribute(HttpClientContext.HTTP_TARGET_HOST);
if("www.baidu.com".equalsIgnoreCase(target.getHostName())){
// keep alive for 5 seconds only 只保持活动5秒
return 5*1000;
}else{
// otherwise keep alive for 30 seconds 否则保持活动30秒
return 30*1000;
}
}
};
CloseableHttpClient client = HttpClients.custom()
.setKeepAliveStrategy(myStrategy)
.build();