文档章节

HttpClient release 与 close connection

b
 bill_wu
发布于 2018/09/18 17:21
字数 769
阅读 13
收藏 0

Apache commons 系列的HttpClient 相信大家都用过,选择它而非JDK 的java.net.HttpURLConnection ,是为了使用HttpClient 封装的几个实用的功能。

目前使用最多的版本还是httpclient-3.x ,在官网http://hc.apache.org/httpclient-3.x/tutorial.html 有这么一段示例代码:

 

 
  1. import org.apache.commons.httpclient.*;

  2. import org.apache.commons.httpclient.methods.*;

  3. import org.apache.commons.httpclient.params.HttpMethodParams;

  4.  
  5. import java.io.*;

  6.  
  7. public class HttpClientTutorial {

  8.  
  9. private static String url = "http://www.apache.org/";

  10.  
  11. public static void main(String[] args) {

  12. // Create an instance of HttpClient.

  13. HttpClient client = new HttpClient();

  14.  
  15. // Create a method instance.

  16. GetMethod method = new GetMethod(url);

  17.  
  18. // Provide custom retry handler is necessary

  19. method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,

  20. new DefaultHttpMethodRetryHandler(3, false));

  21.  
  22. try {

  23. // Execute the method.

  24. int statusCode = client.executeMethod(method);

  25.  
  26. if (statusCode != HttpStatus.SC_OK) {

  27. System.err.println("Method failed: " + method.getStatusLine());

  28. }

  29.  
  30. // Read the response body.

  31. byte[] responseBody = method.getResponseBody();

  32.  
  33. // Deal with the response.

  34. // Use caution: ensure correct character encoding and is not binary data

  35. System.out.println(new String(responseBody));

  36.  
  37. } catch (HttpException e) {

  38. System.err.println("Fatal protocol violation: " + e.getMessage());

  39. e.printStackTrace();

  40. } catch (IOException e) {

  41. System.err.println("Fatal transport error: " + e.getMessage());

  42. e.printStackTrace();

  43. } finally {

  44. // Release the connection.

  45. method.releaseConnection();

  46. }

  47. }

  48. }


大部分人也是以这个为规范来使用的,但是注意有一段关于“Release the Connection”的说明:

 

This is a crucial step to keep things flowing. We must tell HttpClient that we are done with the connection and that it can now be reused. Without doing this HttpClient will wait indefinitely for a connection to free up so that it can be reused.

我看得也不是很明白,意思是我们必须在使用后调用

 

method.releaseConnection();

来告诉HttpClient 这个连接可以重用了。

这个在串行的处理中或许很有用,但是我所遇到的情况是多线程并发下,不能共享同一个HttpClient 实例,按照官方示例写好代码后,程序跑起来似乎没什么问题,但是随着时间的累计,有一天突然发现这个模块不工作了,查看了一下当前的网络连接,这个java 程序同一个地址保持着200多个CLOSE_WAIT 的连接,好吧,连接没有释放。

为什么没有释放?查看doc,有这样的说明:

 

Releases the connection being used by this HTTP method. In particular the connection is used to read the response(if there is one) and will be held until the response has been read. If the connection can be reused by other HTTP methods it is NOT closed at this point.


注意最后一句,如果该连接可以重用则不关闭,是“可以重用”,当然可以重用了,就在那儿等着我去重用,可是我都是新建的实例,怎么重用

查看源码,找到HttpClient 的构造方法,有一个可以指定HttpConnectionManager ,然后这个HttpConnectionManager 又有一个实现的构造:

 

 
  1. public SimpleHttpConnectionManager(boolean alwaysClose)

  2. 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 false. Otherwise the connection manager will always close connections upon release.

  3. Parameters:

  4. alwaysClose - if set true, the connection manager will always close connections upon release.


显然alawaysClose 的默认值是false ,在释放后连接并不总是会关闭。

所以,必须

 

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


当然,还有其它的解决方案,找到了一篇文章总结的比较全面:HttpClient容易忽视的细节——连接关闭

本文转载自:https://blog.csdn.net/wujun8/article/details/41726769

b
粉丝 1
博文 27
码字总数 3992
作品 0
广州
私信 提问
HttpComponents Client 5.0 Alpha1 发布

HttpComponents Client 5.0 Alpha1 发布,主要更新如下: * Improved conformance to requirements and recommendations of the latest HTTP/1.1 protocol specification (RFC 7230, RFC 723......

淡漠悠然
2016/01/29
981
0
Apache HttpClient 资源释放、请求超时,导致线程池用光、内存不足

Apache HttpClient,据说很强大,可以支持峰值一秒7万以上的请求。不过需要注意一些资源释放和超时处理的问题。 问题1:线程资源无法释放,最终导致内存不足、或线程池被用光。 问题代码: ...

onedotdot
2018/10/17
0
0
httpclient4.4 出现NoHttpResponseException的异常解决

httpclient4.4简单初始化httpclient的方式: 使用连接池初始化httpclient的方式: 但在测试过程中发现,有时候出现如下的异常,但重试一次就没有问题: 网上查了相关的报错信息,找到官网上的...

一路向北的兔斯基
2015/07/30
0
1
采用httpClient拉取服务端数据,偶尔会出现异常:java.net.SocketException: Software caused connection abort: recv failed

用httpClient发送http请求,拉取服务端的数据,不定时会出现下面的异常: 网络异常,堆栈轨迹如下 java.net.SocketException: Software caused connection abort: recv failed at java.net.So...

juque
2018/03/06
478
0
HttpComponents Client 4.4.1 GA 发布,HTTP 协议库

Apache HttpComponents Client 4.4.1 GA 发布,此版本主要更新信息如下: Marked RFC 2109, RFC 2965, Netscape draft cookie specs as obsolete Contributed by Oleg Kalnichevski [HTTPCLI......

oschina
2015/04/02
2.2K
7

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周二乱弹 —— 你一辈子都不可能跟她这么亲近

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享George Benson的单曲《Six Play》: 《Six Play》- George Benson 手机党少年们想听歌,请使劲儿戳(这里) ...

小小编辑
37分钟前
256
8
优雅的关闭Spring Boot

优雅的关闭Spring Boot 1、实现 TomcatConnectorCustomizer 接口拿到Tomcat的连接获取 Tomcat连接池 2、实现 ApplicationListener<ContextClosedEvent> 监听服务器关闭事件,注册JVM钩子函数...

sowhat
今天
2
0
Python3-Web开发

简介 Web开发框架 什么是Web框架? Web应用程序框架或简单的Web框架表示一组库和模块,使Web应用程序开发人员能够编写应用程序,而不必担心协议,线程管理等低级细节。 virtualenv是一个虚拟...

wuxinshui
今天
4
0
使用技媒体实践编写发布博客

技媒体实践博客 CSDN OSChina 知乎 简书 思否 掘金 51CTO

晨猫
今天
3
0
Lucene

1、什么是全文检索 数据分类 我们生活中的数据总体分为两种:结构化数据和非结构化数据。 结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。 非结构化数据:指不定长或无固...

榴莲黑芝麻糊
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部