HttpClient如何 关闭链接(转)

ava代码html

  1. HttpClient client = new HttpClient();   
  2. HttpMethod method = new GetMethod("http://www.apache.org");   
  3. try {   
  4.   client.executeMethod(method);   
  5.   byte[] responseBody = null;   
  6.      
  7.   responseBody = method.getResponseBody();   
  8.      
  9. catch (HttpException e) {   
  10.   // TODO Auto-generated catch block   
  11.   e.printStackTrace();   
  12. catch (IOException e) {   
  13.   // TODO Auto-generated catch block   
  14.   e.printStackTrace();   
  15. }finally{   
  16.   method.releaseConnection();   
  17.      
  18. }  


大部分人使用HttpClient都是使用相似上面的代码,由于Apache官方例子就是如此。但在使用HttpClient会发现若是不断循环发送大量请求到服务器会致使APACHE服务器的链接被占满,后续的请求便排队等待,程序陷入“假死”状态。apache

Java代码
  1. Timeout 30  
  2. KeepAlive On   #表示服务器端不会主动关闭连接   
  3. MaxKeepAliveRequests 100  
  4. KeepAliveTimeout 180   

所以这样的配置就会致使每一个连接至少要过180S才会被释放,这样在大量请求访问时就必然会形成链接被占满,请求等待的状况。
在 经过DEBUG后发现HttpClient在method.releaseConnection()后并无把链接关闭,这个方法只是将 链接返回给 connection manager。若是使用HttpClient client = new HttpClient()实例化一个HttpClient connection manager默认实现是使用SimpleHttpConnectionManager。SimpleHttpConnectionManager有个构 造函数以下
Java代码
  1.   
  2. public SimpleHttpConnectionManager(boolean alwaysClose) {   
  3.     super();   
  4.     this.alwaysClose = alwaysClose;   
  5. }  

看 方法注释咱们就能够看到若是alwaysClose设为true在连接释放以后connection manager 就会关闭链。在咱们HttpClient client = new HttpClient()这样实例化一个client时connection manager是这样被实例化的
Java代码
  1. this.httpConnectionManager = new SimpleHttpConnectionManager();  

所以alwaysClose默认是false,connection是不会被主动关闭的,所以咱们就有了一个客户端关闭连接的方法。
方法一:
把事例代码中的第一行实例化代码改成以下便可,在method.releaseConnection();以后connection manager会关闭connection 。
Java代码
  1. HttpClient client = new HttpClient(new HttpClientParams(),new SimpleHttpConnectionManager(true) );  

方法二:
实例化代码使用:HttpClient client = new HttpClient();
在method.releaseConnection();以后加上
Java代码
  1. ((SimpleHttpConnectionManager)client.getHttpConnectionManager()).shutdown();  

shutdown源代码很简单,看了一目了然
Java代码
  1. public void shutdown() {   
  2.     httpConnection.close();   
  3. }  

方法三:
实例化代码使用:HttpClient client = new HttpClient();
在method.releaseConnection();以后加上
client.getHttpConnectionManager().closeIdleConnections(0);此方法源码代码以下:
Java代码
  1. public void closeIdleConnections(long idleTimeout) {   
  2.     long maxIdleTime = System.currentTimeMillis() - idleTimeout;   
  3.     if (idleStartTime <= maxIdleTime) {   
  4.         httpConnection.close();   
  5.     }   
  6. }  

将idleTimeout设为0能够确保连接被关闭。
以上这三种方法都是有客户端主动关闭TCP连接的方法。下面再介绍由服务器端自动关闭连接的方法。
方法四:
代码实现很简单,全部代码就和最上面的事例代码同样。只须要在HttpMethod method = new GetMethod("http://www.apache.org");加上一行HTTP头的设置便可
Java代码
  1. method.setRequestHeader("Connection""close");  

看一下HTTP协议中关于这个属性的定义:
HTTP/1.1 defines the "close" connection option for the sender to signal that the connection will be closed after completion of the response. For example,
       Connection: close
如今再说一下客户端关闭连接和服务器端关闭连接的区别。若是采用客户端关闭连接的方法,在客户端的机器上使用netstat –an命令会看到不少TIME_WAIT的TCP连接。若是服务器端主动关闭连接这中状况就出如今服务器端。
参考WIKI上的说明http://wiki.apache.org/HttpComponents/FrequentlyAskedConnectionManagementQuestions
The TIME_WAIT state is a protection mechanism in TCP. The side that closes a socket connection orderly will keep the connection in state TIME_WAIT for some time, typically between 1 and 4 minutes.
TIME_WAIT的状态会出如今主动关闭链接的这一端。TCP协议中TIME_WAIT状态主要是为了保证数据的完整传输。具体能够参考此文档:
http://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html#ss2.7
另外强调一下使用上面这些方法关闭连接是在咱们的应用中明确知道不须要重用链接时能够主动关闭链接来释放资源。若是你的应用是须要重用接的话就不必这么作,使用原有的接还能够提供性能。
相关文章
相关标签/搜索