ESTABLISHED 表示正在进行网络连接的数量 
TIME_WAIT 表示表示等待系统主动关闭网络连接的数量 
CLOSE_WAIT 表示被动等待程序关闭的网络连接数量

上篇文章给出了解决TIME_WAIT太多的方法,本篇文章以HttpClient为例说明解决大量CLOSE_WAIT状态的方法。

HttpClient是大量使用的用于HTTP连接的包,首先需要说明的是HttpClient 3.x和4.x之间API差距很多,不过强烈建议使用4.x的版本。除此之外,4.x中每个x之间也有一些差别(比如一些弃用的类,新增加的类等),这里以4.2.3版本进行说明。

HttpClient使用的HTTP 1.1协议进行连接,相对于HTTP 1.0来说有一个持续连接的增强,为了充分利用持续连接的特性,在一次连接结束之后,即使将HttpResponse使用close方法关闭,并且将调用了HttpGet或HttpPost的releaseConnection方法,示例代码如下:

 HttpGet method = null;
HttpResponse response = null;
try {
method = new HttpGet(url);
response = client.execute(method);
} catch(Exception e) { } finally {
if(response != null) {
EntityUtils.consumeQuietly(response.getEntity());
}
if(method != null) {
method.releaseConnection();
}
}

这个时候仍然发现连接处于CLOSE_WAIT状态,这是因为HttpClient在执行close的时候,如果发现Response的Header中Connection是Keep-alive则连接不会关闭,以便下次请求相同网站的时候进行复用,这是产生CLOSE_WAIT连接的原因所在。

最简单的一种解决方法在execute方法之前增加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

示例代码如下:

HttpGet method = null;
HttpResponse response = null;
try {
method = new HttpGet(url);
method.setHeader(HttpHeaders.CONNECTION, "close");
response = client.execute(method);
} catch(Exception e) { } finally {
if(response != null) {
EntityUtils.consumeQuietly(response.getEntity());
}
if(method != null) {
method.releaseConnection();
}
}

当然,也可以每次请求之后关闭client,但这一点不符合HttpClient设计的原则——复用。如果每次连接完成之后就关闭连接,效率太低了。因此,需要使用PoolingClientConnectionManager,并且设置maxTotal(整个连接池里面最大连接数,默认为20)和defaultMaxPerRoute(每个主机的最大连接数,默认为2),另外client还有一个ClientPNames.CONN_MANAGER_TIMEOUT参数,用来设置当连接不够获取新连接等待的超时时间,默认和CoreConnectionPNames.CONNECTION_TIMEOUT相同。可以根据实际情况对PoolingClientConnectionManager进行设置,以达到效率最优。

还有一种情况也会造成大量CLOSE_WAIT连接,即HttpResponse的状态码不是200的时候,需要及时调用method.abort()方法对连接进行释放,详细可以参考这篇文章。https://blog.csdn.net/eff666/article/details/78240503

最新文章

  1. js判断当前页面在移动设备还是在PC端中打开
  2. iOS开发UI篇—CAlayer层的属性
  3. django--模板(七)
  4. 自定义View(二)增加View的属性
  5. Using python to process Big Data
  6. JavaScript入门
  7. CentOS + Nginx + PHP-FPM(FastCGI) 配置CodeIgniter
  8. Java 嵌套作用域
  9. asp.net 检查文件夹和文件是否存在
  10. ACM/ICPM2014鞍山现场赛D Galaxy (HDU 5073)
  11. Mac系统编译FFmpeg
  12. Tomcat服务相关配置
  13. SkylineGlobe 如何二次开发获取三维模型的BBOX和设置Tint属性
  14. Python3 tkinter基础 Canvas create_text 在画布上添加文字
  15. Linux下的文件操作——基于文件描述符的文件操作(2)
  16. 51nod 1967 路径定向(不错的欧拉回路)
  17. discuz回贴通知插件实现-配置邮件服务器
  18. RecyclerView分隔线定制
  19. .NET 命令行参数包含应用程序路径吗?
  20. 批处理实现mysql的备份

热门文章

  1. kettle基于时间戳增量更新
  2. Kafka-python 客户端导致的 cpu 使用过高,且无法消费消息的问题
  3. "unexpected console statement” in Node.js
  4. error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler op
  5. springdataJAP的更新与保存的方法是同一个
  6. poj3436(拆点最大流)
  7. stop()在animate中的用法
  8. 数据分析---《Python for Data Analysis》学习笔记【03】
  9. CF24D Broken robot
  10. rsync实时同步服务部署