`
shuaigg.babysky
  • 浏览: 567545 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

HttpClient容易忽视的细节--连接关闭

阅读更多

Java代码

  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 client = new HttpClient();

HttpMethod method = new GetMethod("http://www.apache.org");

try {

  client.executeMethod(method);

  byte[] responseBody = null;

 

  responseBody = method.getResponseBody();

 

} catch (HttpException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

} catch (IOException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

}finally{

  method.releaseConnection();

 

}


大部分人使用HttpClient都是使用类似上面的事例代码,包括Apache官方的例子也是如此。最近我在使用HttpClient是发现一次循环发送大量请求到服务器会导致APACHE服务器的链接被占满,后续的请求便排队等待。
我服务器端APACHE的配置

Java代码

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

Timeout 30

KeepAlive On   #表示服务器端不会主动关闭链接

MaxKeepAliveRequests 100

KeepAliveTimeout 180


因此这样的配置就会导致每个链接至少要过180S才会被释放,这样在大量请求访问时就必然会造成链接被占满,请求等待的情况。
在通过DEBUH后发现HttpClientmethod.releaseConnection()后并没有把链接关闭,这个方法只是将链接返 回给connection manager。如果使用HttpClient client = new HttpClient()实例化一个HttpClient connection manager默认实现是使用SimpleHttpConnectionManagerSimpleHttpConnectionManager有个构造函数如下

Java代码

  1. /** 
  2.  * The connection manager created with this constructor will try to keep the  
  3.  * connection open (alive) between consecutive requests if the alwaysClose  
  4.  * parameter is set to <tt>false</tt>. Otherwise the connection manager will  
  5.  * always close connections upon release. 
  6.  *  
  7.  * @param alwaysClose if set <tt>true</tt>, the connection manager will always 
  8.  *    close connections upon release. 
  9.  */  
  10. public SimpleHttpConnectionManager(boolean alwaysClose) {  
  11.     super();  
  12.     this.alwaysClose = alwaysClose;  
  13. }  

/**

 * The connection manager created with this constructor will try to keep the

 * connection open (alive) between consecutive requests if the alwaysClose

 * parameter is set to <tt>false</tt>. Otherwise the connection manager will

 * always close connections upon release.

 *

 * @param alwaysClose if set <tt>true</tt>, the connection manager will always

 *    close connections upon release.

 */

public SimpleHttpConnectionManager(boolean alwaysClose) {

    super();

    this.alwaysClose = alwaysClose;

}


看方法注释我们就可以看到如果alwaysClose设为true在链接释放之后connection manager 就会关闭链。在我们HttpClient client = new HttpClient()这样实例化一个clientconnection manager是这样被实例化的

Java代码

  1. this.httpConnectionManager = new SimpleHttpConnectionManager();  

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(new HttpClientParams(),new SimpleHttpConnectionManager(true) );


方法二:
实例化代码使用:HttpClient client = new HttpClient();
method.releaseConnection();之后加上

Java代码

  1. ((SimpleHttpConnectionManager)client.getHttpConnectionManager()).shutdown();  

((SimpleHttpConnectionManager)client.getHttpConnectionManager()).shutdown();


shutdown
源代码很简单,看了一目了然

Java代码

  1. public void shutdown() {  
  2.     httpConnection.close();  
  3. }  

public void shutdown() {

    httpConnection.close();

}


方法三:
实例化代码使用: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. }  

public void closeIdleConnections(long idleTimeout) {

    long maxIdleTime = System.currentTimeMillis() - idleTimeout;

    if (idleStartTime <= maxIdleTime) {

        httpConnection.close();

    }

}


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

Java代码

  1. method.setRequestHeader("Connection", "close");  

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_WAITTCP链接。如果服务器端主动关闭链接这中情况就出现在服务器端。
参考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
另外强调一下使用上面这些方法关闭链接是在我们的应用中明确知道不需要重用链接时可以主动关闭链接来释放资源。如果你的应用是需要重用链接的话就没必要这么做,使用原有的链接还可以提供性能。

 

 

分享到:
评论

相关推荐

    httpclient5-fluent-5.0.3.jar

    这是我一个抠图程序发送请求时专用的jar,maven仓库不好下载,我就上传到csdn,以便下次可以继续使用

    httpclient-4.4.1-API文档-中文版.zip

    赠送jar包:httpclient-4.4.1.jar; 赠送原API文档:httpclient-4.4.1-javadoc.jar; 赠送源代码:httpclient-4.4.1-sources.jar; 赠送Maven依赖信息文件:httpclient-4.4.1.pom; 包含翻译后的API文档:httpclient...

    httpclient-4.5.13-API文档-中文版.zip

    赠送jar包:httpclient-4.5.13.jar; 赠送原API文档:httpclient-4.5.13-javadoc.jar; 赠送源代码:httpclient-4.5.13-sources.jar; 赠送Maven依赖信息文件:httpclient-4.5.13.pom; 包含翻译后的API文档:...

    httpcore-4.2.4,httpclient-4.2.5,httpclient-cache-4.2.5,httpmime-4.2.5的jar包下载

    它包含了HTTP连接的建立、保持和关闭,以及HTTP方法(GET, POST等)的实现。HTTP Core还支持传输编码(如chunked编码),内容编码(如gzip压缩)和HTTP连接的复用,这极大地提高了网络通信的效率。 **httpclient-...

    httpclient-4.5.12-API文档-中英对照版.zip

    赠送jar包:httpclient-4.5.12.jar; 赠送原API文档:httpclient-4.5.12-javadoc.jar; 赠送源代码:httpclient-4.5.12-sources.jar; 赠送Maven依赖信息文件:httpclient-4.5.12.pom; 包含翻译后的API文档:...

    httpclient-4.5.6-API文档-中文版.zip

    赠送jar包:httpclient-4.5.6.jar; 赠送原API文档:httpclient-4.5.6-javadoc.jar; 赠送源代码:httpclient-4.5.6-sources.jar; 赠送Maven依赖信息文件:httpclient-4.5.6.pom; 包含翻译后的API文档:httpclient...

    httpclient-4.5.13-API文档-中英对照版.zip

    赠送jar包:httpclient-4.5.13.jar; 赠送原API文档:httpclient-4.5.13-javadoc.jar; 赠送源代码:httpclient-4.5.13-sources.jar; 赠送Maven依赖信息文件:httpclient-4.5.13.pom; 包含翻译后的API文档:...

    commons-httpclient-3.0-rc4

    httpclient常用的jar包,便于大家使用

    httpclient-4.5.2-API文档-中英对照版.zip

    赠送jar包:httpclient-4.5.2.jar; 赠送原API文档:httpclient-4.5.2-javadoc.jar; 赠送源代码:httpclient-4.5.2-sources.jar; 包含翻译后的API文档:httpclient-4.5.2-javadoc-API文档-中文(简体)-英语-对照...

    commons-httpclient-3.0.1--java网络开发

    package org.apache.commons.httpclient; // Imports import java.io.IOException; import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.commons.logging.Log; public class ...

    httpclient-4.5.6-API文档-中英对照版.zip

    赠送jar包:httpclient-4.5.6.jar; 赠送原API文档:httpclient-4.5.6-javadoc.jar; 赠送源代码:httpclient-4.5.6-sources.jar; 赠送Maven依赖信息文件:httpclient-4.5.6.pom; 包含翻译后的API文档:httpclient...

    httpclient-4.5.5-API文档-中文版.zip

    赠送jar包:httpclient-4.5.5.jar; 赠送原API文档:httpclient-4.5.5-javadoc.jar; 赠送源代码:httpclient-4.5.5-sources.jar; 包含翻译后的API文档:httpclient-4.5.5-javadoc-API文档-中文(简体)版.zip ...

    httpclient-4.5jar

    httpclient-4.5所需jar包,里面包含httpclient-4.5.jar等等10个必须的开发包。 1.commons-codec-1.9.jar 2.commons-logging-1.2.jar 3.fluent-hc-4.5.jar 4.httpclient-4.5.jar 5.httpclient-cache-4.5.jar 6....

    wechatpay-apache-httpclient-0.2.1.jar

    wechatpay-apache-httpclient-0.2.1.jar

    httpclient-4.1-alpha1.jar

    httpclient-4.1-alpha1.jar httpclient-4.1-alpha1.jar httpclient-4.1-alpha1.jar httpclient-4.1-alpha1.jar httpclient-4.1-alpha1.jar

    httpclient-4.5.10-API文档-中文版.zip

    赠送jar包:httpclient-4.5.10.jar; 赠送原API文档:httpclient-4.5.10-javadoc.jar; 赠送源代码:httpclient-4.5.10-sources.jar; 赠送Maven依赖信息文件:httpclient-4.5.10.pom; 包含翻译后的API文档:...

    httpclient-tutorial-simplified-chinese

    **6.1 自定义客户端连接**:允许开发者自定义连接的细节。 **6.2 有状态的 HTTP 连接** - **用户令牌处理器**:处理用户的令牌。 - **用户令牌和执行上下文**:描述了如何在执行上下文中管理用户令牌。 通过以上...

    amber-oauth2-httpclient4-0.22-incubating.zip

    标签:amber-oauth2-httpclient4-0.22-incubating.zip,amber,oauth2,httpclient4,0.22,incubating.zip包下载,依赖包

    httpclient-cache-4.5.jar

    用于http请求的jar包

    httpcomponents-httpclient-4.5.8-bin-src.zip

    httpclient-4.5.8.jar; httpclient-cache-4.5.8.jar; httpclient-osgi-4.5.8.jar; httpclient-win-4.5.8.jar; httpcore-4.4.11.jar; httpmime-4.5.8.jar; jna-4.5.2.jar; jna-platform-4.5.2.jar

Global site tag (gtag.js) - Google Analytics