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——连接关闭的更多相关文章
- HttpClient如何 关闭连接(转)
ava代码 HttpClient client = new HttpClient(); HttpMethod method = new GetMethod("http://www.apach ...
- HttpClient连接池的连接保持、超时和失效机制
HTTP是一种无连接的事务协议,底层使用的还是TCP,连接池复用的就是TCP连接,目的就是在一个TCP连接上进行多次的HTTP请求从而提高性能.每次HTTP请求结束的时候,HttpClient会判断连 ...
- HttpClient连接池抛出大量ConnectionPoolTimeoutException: Timeout waiting for connection异常排查
转自: http://blog.csdn.net/shootyou/article/details/6615051 今天解决了一个HttpClient的异常,汗啊,一个HttpClient使用稍有不慎 ...
- Http持久连接与HttpClient连接池
一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...
- Http 持久连接与 HttpClient 连接池
一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...
- HttpClient连接池
HttpClient连接池,发现对于高并发的请求,效率提升很大.虽然知道是因为建立了长连接,导致请求效率提升,但是对于内部的原理还是不太清楚.后来在网上看到了HTTP协议的发展史,里面提到了一个属性C ...
- httpClient 连接池问题出现403.9
困扰了半个月时间终于找到连接池的问题,由于调用第三方有异常导致连接不能及时释放 所以写了一个定时扫描释放连接 监控连接池释放连接: public static class IdleConnection ...
- (五)HttpClient 连接超时及读取超时
第一节: HttpClient 连接超时及读取超时 HttpClient连接超时及读取超时 httpClient在执行具体http请求时候 有一个连接的时间和读取内容的时间: HttpClient连接 ...
- HttpClient连接超时及读取超时
HttpClient连接超时及读取超时 httpClient在执行具体http请求时候 有一个连接的时间和读取内容的时间: HttpClient连接时间 所谓连接的时候 是HttpClient发送请求 ...
随机推荐
- Note++ 的快捷
Notepad++绝对是windows下进行程序编辑的神器之一,要更快速的使用以媲美VIM,必须灵活掌握它的快捷键,下面对notepad++默认的快捷键做个整理(其中有颜色的为常用招数): Ctrl+ ...
- 从源代码制作deb包的两种方法以及修改已有deb包(转载)
From:http://yysfire.github.io/linux/%E4%BB%8E%E6%BA%90%E4%BB%A3%E7%A0%81%E5%88%B6%E4%BD%9Cdeb%E5%8C% ...
- 原密码忘了,重置MAC开机密码
如果登陆密码忘了,或者你接手了一台前任同事的MAC,而他设了密码没告诉你,你可以这样: 1.重启MAC,然后在启动时按下:CMD+S 2.进入命令行格式后输入:fsck -y (file system ...
- c# WMI获取机器硬件信息(硬盘,cpu,内存等)
using System; using System.Collections.Generic; using System.Globalization; using System.Management; ...
- C语言中access、_mkdir、sprintf、 fopen、fwrite函数
int access(const char *filename, int amode); amode参数为0时表示检查文件的存在性,如果文件存在,返回0,不存在,返回-. 这个函数还可以检查其它文件属 ...
- java -d64
在 resin启动时指定java时加上了 -d64选项 JAVA="/xx/java -d64" 选择 "-server"选项必须使用-d64 http://b ...
- CRM IFRAME 显示地图
作者:卞功鑫 ,转载请保留.http://www.cnblogs.com/BinBinGo/p/5274409.html 需要背景: 现在已经有经纬度,需要在地图上显示出来. 环境: CRM 4.0 ...
- mybatis模板
因为这里是说mybatis的,所以呢 servlet就不做多说了,代码也不在这里贴出来了. log4j.properties log4j.rootLogger=DEBUG,Console log4j. ...
- [SQL]patindex的用法
返回指定表达式中某模式第一次出现的起始位置:如果在全部有效的文本和字符数据类型中没有找到该模式,则返回零. Transact-SQL 语法约定 语法 PATINDEX ( '%pattern%' , ...
- Java的四种引用
1.强引用(StrongReference)强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程 ...