`
gzcj
  • 浏览: 291204 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

httpclient链接关闭问题(转帖)

阅读更多
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的配置

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


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

/**
 * 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()这样实例化一个client时connection manager是这样被实例化的

this.httpConnectionManager = new SimpleHttpConnectionManager();


因此alwaysClose默认是false,connection是不会被主动关闭的,因此我们就有了一个客户端关闭链接的方法。
方法一:
把事例代码中的第一行实例化代码改为如下即可,在method.releaseConnection();之后connection manager会关闭connection 。

HttpClient client = new HttpClient(new HttpClientParams(),new SimpleHttpConnectionManager(true) );


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

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


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

public void shutdown() {
    httpConnection.close();
}


方法三:
实例化代码使用:HttpClient client = new HttpClient();
在method.releaseConnection();之后加上
client.getHttpConnectionManager().closeIdleConnections(0);此方法源码代码如下:

 
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头的设置即可

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

分享到:
评论

相关推荐

    关闭HttpClient日志的logback文件

    关闭HttpClient日志的logback文件

    彻底解决httpClient乱码问题

    本文将深入探讨如何使用HttpClient来彻底解决乱码问题。 HttpClient是一个功能强大的HTTP客户端,支持多种HTTP协议版本,包括GET、POST等请求方法,以及重试、连接管理等功能。在处理中文字符时,由于编码不一致...

    httpClient 网络传输的实例

    1. **创建HttpClient对象**:首先,我们需要创建一个HttpClient实例,这通常是通过HttpClientBuilder或HttpAsyncClientBuilder构建的。例如: ```java CloseableHttpClient httpClient = HttpClients.create...

    使用httpclient解决跨域问题

    我使用的是httpClient 进行内部转发 我们在A的服务器上,将前台的文件流,通过httpClient传输到B的服务器上(B的服务器通过控制层接受A传输的文件流,让后保存在B的服务器上。返回一个json结果)

    httpclient.jar包下载

    1. **连接管理**:HttpClient通过HttpConnectionManager接口控制HTTP连接的创建、复用和关闭,有效地管理连接池,避免了频繁建立新连接带来的性能开销。 2. **请求和响应模型**:HttpClient使用HttpRequest和...

    httpclient httpclient.jar

    注意,每次操作完成后,都需要关闭响应和HttpClient实例以释放资源。 HttpClient还支持更复杂的用法,如POST请求、文件上传、Cookie管理、HTTPS通信、自定义连接管理器等。通过深入学习HttpClient,你可以更灵活地...

    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....

    httpclient

    4. **重试策略**:当请求失败时,HttpClient可以根据预设的策略决定是否重试,避免因网络问题导致的错误。 5. **请求与响应处理**:HttpClient允许自定义请求头,处理响应头,以及对请求和响应实体内容的编码和解码...

    使用httpClient访问https+443端口号。

    8. **关闭连接**:记得在完成请求后关闭HttpClient和响应实体,以释放资源。 9. **错误处理**:处理可能出现的异常,如网络问题、认证失败或证书问题。 通过这些步骤,我们可以使用Apache HttpClient库安全地与443...

    HttpClientHelper 工具类

    5. **异常处理**:HttpClientHelper 应该包含了适当的错误处理机制,如捕获网络异常、解析异常等,以确保在出现问题时能够给出适当的反馈。 6. **HTTP请求配置**:可能还提供了设置超时、添加HTTP头、携带Cookie等...

    HttpClient 3.x to HttpComponents HttpClient 4.x

    例如,在HttpClient 3.x中,代码可能会使用`***mons.httpclient.HttpClient`类和`***mons.httpclient.methods.GetMethod`等,而在4.x版本中,这些都被新的API所替代。程序员需要熟悉`org.apache....

    httpClient

    // 发生致命的异常,可能是协议不对或者返回的内容有问题 System.out.println("请检查输入的URL!"); e.printStackTrace(); } catch (IOException e) { // 发生网络异常 System.out.println("发生网络异常!"); ...

    解决HttpClient中文乱码问题jar文件

    HttpClient中文乱码问题的核心在于字符编码不一致或者未明确指定。默认情况下,HttpClient可能使用ISO-8859-1作为编码,而我们的中文字符通常需要UTF-8编码才能正确显示。以下是一些解决HttpClient中文乱码问题的...

    httpclient官网教程中文版

    ### Httpclient官网教程中文版知识点总结 #### 一、引言 HTTP协议作为互联网的核心通信标准之一,在现代网络服务及物联网设备中扮演着至关重要的角色。随着技术的发展,越来越多的应用和服务依赖于HTTP协议来实现...

    HttpClient 调用WebService示例

    8. **关闭HttpClient**: 记得在完成所有操作后关闭HttpClient,以释放资源: ```java httpClient.close(); ``` 以上就是使用HttpClient调用WebService的基本步骤。实际应用中,你可能需要根据具体的WebService...

    Arduino HttpClient 库文件

    6. **关闭连接**:请求完成后,记得调用 `client.stop()` 关闭连接,释放资源。 注意,由于 Arduino 的内存限制,HttpClient 库可能不适用于大数据量的传输。此外,HTTP 请求可能受网络条件、服务器响应时间和 ...

    httpClient需要的jar包

    HttpClient是Apache基金会开发的一个Java库,它为Java程序员提供了一个强大的、灵活的、稳定的、功能丰富的客户端HTTP通信框架。...同时,及时关注Apache HttpClient的更新,以便利用新特性并修复已知问题。

Global site tag (gtag.js) - Google Analytics