转载自--http://blog.csdn.net/shootyou/article/details/6415248
在一次服务器异常的排查过程当中(服务器异常排查的过程我会另起文章),我们决定使用HttpClient4.X替代HttpClient3.X或者HttpConnection。
为什么使用HttpClient4?主要是HttpConnection没有连接池的概念,多少次请求就会建立多少个IO,在访问量巨大的情况下服务器的IO可能会耗尽。
HttpClient3也有连接池的东西在里头,使用MultiThreadedHttpConnectionManager,大致过程如下:
- MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
- HttpClient client = new HttpClient(connectionManager);...// 在某个线程中。
- GetMethod get = new GetMethod("http://jakarta.apache.org/");
- try {
- client.executeMethod(get);// print response to stdout
- System.out.println(get.getResponseBodyAsStream());
- } finally {
- // be sure the connection is released back to the connection
- managerget.releaseConnection();
- }
可以看出来,它的方式与jdbc连接池的使用方式相近,我觉得比较不爽的就是需要手动调用releaseConnection去释放连接。对每一个HttpClient.executeMethod须有一个method.releaseConnection()与之匹配。
HttpClient4在这点上做了改进,使用我们常用的InputStream.close()来确认连接关闭(4.1版本之前使用entity.consumeContent()来确认内容已经被消耗关闭连接)。具体方式如下:
- ...HttpClient client = null;InputStream in = null;
- try{
- client = HttpConnectionManager.getHttpClient();
- HttpGet get = new HttpGet();
- get.setURI(new URI(urlPath));
- HttpResponse response = client.execute(get);
- HttpEntity entity =response.getEntity();
- if( entity != null ){
- in = entity.getContent();
- ....
- }catch (Exception e){
- ....
- }finally{
- if (in != null){
- try{in.close ();}catch (IOException e){
- e.printStackTrace ();
- }
- }
- }
2012-03-06更新:
有网友提出调用in.close()是否会关闭底层socket,事情是这样的:
- 回复kangkang203:感谢你提出的这个问题。
- 首先我文中提出的方法in.close()它会触发一个连接的释放这个连接将重新被连接管理器收回,官网的原文是这么说的:“Closing the input stream will trigger connection release...the underlying connection gets released back to the connection manager”。但是底层的socket是否会被关闭是不一定的,我看了部分源码(EofSensorInputStream)发现,大多数情况socket并不会关闭,而是否关闭socket貌似是由一个Watcher去决定的。所以in.close的调用不会引起socket的关闭。
- 另外,由于http本身我们把它当做“短连接”,所以在一次请求交互完成后仍然打开socket的意义不是很大,毕竟它不像长连接那样在一个连接建立之后会有很多次数据交互。我们试用连接管理器的更多意义在于它对连接的管理。
好说完了连接池的使用流程,现在来说一说连接池在使用时最重要的几个参数。我用4.1的版本实现了一个简单的HttpConnectionManager,代码如下:
- public class HttpConnectionManager {
- private static HttpParams httpParams;
- private static ClientConnectionManager connectionManager;
- /**
- * 最大连接数
- */
- public final static int MAX_TOTAL_CONNECTIONS = 800;
- /**
- * 获取连接的最大等待时间
- */
- public final static int WAIT_TIMEOUT = 60000;
- /**
- * 每个路由最大连接数
- */
- public final static int MAX_ROUTE_CONNECTIONS = 400;
- /**
- * 连接超时时间
- */
- public final static int CONNECT_TIMEOUT = 10000;
- /**
- * 读取超时时间
- */
- public final static int READ_TIMEOUT = 10000;
- static {
- httpParams = new BasicHttpParams();
- // 设置最大连接数
- ConnManagerParams.setMaxTotalConnections(httpParams, MAX_TOTAL_CONNECTIONS);
- // 设置获取连接的最大等待时间
- ConnManagerParams.setTimeout(httpParams, WAIT_TIMEOUT);
- // 设置每个路由最大连接数
- ConnPerRouteBean connPerRoute = new ConnPerRouteBean(MAX_ROUTE_CONNECTIONS);
- ConnManagerParams.setMaxConnectionsPerRoute(httpParams,connPerRoute);
- // 设置连接超时时间
- HttpConnectionParams.setConnectionTimeout(httpParams, CONNECT_TIMEOUT);
- // 设置读取超时时间
- HttpConnectionParams.setSoTimeout(httpParams, READ_TIMEOUT);
- SchemeRegistry registry = new SchemeRegistry();
- registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
- registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
- connectionManager = new ThreadSafeClientConnManager(httpParams, registry);
- }
- public static HttpClient getHttpClient() {
- return new DefaultHttpClient(connectionManager, httpParams);
- }
- }
最大连接数、获取连接的最大等待时间、读取超时时间 这些配置应该比较容易理解,一般的连接池都会有这些配置,比较特别的是 每个路由(route)最大连接数 。
什么是一个route?
这里route的概念可以理解为 运行环境机器 到 目标机器的一条线路。举例来说,我们使用HttpClient的实现来分别请求 www.baidu.com 的资源和 www.bing.com 的资源那么他就会产生两个route。
这里为什么要特别提到route最大连接数这个参数呢,因为这个参数的默认值为2,如果不设置这个参数值默认情况下对于同一个目标机器的最大并发连接只有2个!这意味着如果你正在执行一个针对某一台目标机器的抓取任务的时候,哪怕你设置连接池的最大连接数为200,但是实际上还是只有2个连接在工作,其他剩余的198个连接都在等待,都是为别的目标机器服务的。
怎么样蛋疼吧,我是已经有过血的教训了,在切换到HttpClient4.1的起初没有注意到这个配置,最后使得服务承受的压力反而不如从前了,所以在这里特别提醒大家注意。
HttpClient4.X 教程下载:
关于版本的补充:
网友w2449008821提醒之后我才发现在HttpClient4.1+的版本ConnManagerParams已经被Deprecated了。
我在写这篇日志的时候时候的httpclient 版本是4.0.3,从4.0版本之后ConnManagerParams被Deprecated,没想到一个小版本升级会有这么大变化。
官网教程举例了新的连接池设置:
- SchemeRegistry schemeRegistry = new SchemeRegistry();
- schemeRegistry.register(
- new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
- schemeRegistry.register(
- new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
- ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry);
- // Increase max total connection to 200
- cm.setMaxTotalConnections(200);
- // Increase default max connection per route to 20
- cm.setDefaultMaxPerRoute(20);
- // Increase max connections for localhost:80 to 50
- HttpHost localhost = new HttpHost("locahost", 80);
- cm.setMaxForRoute(new HttpRoute(localhost), 50);
- HttpClient httpClient = new DefaultHttpClient(cm);
ConnManagerParams的功能被挪到了 ThreadSafeClientConnManager 和 HttpConnectionParams两个类:
static ConnPerRoute |
getMaxConnectionsPerRoute(HttpParams params) Deprecated. use ThreadSafeClientConnManager.getMaxForRoute(org.apache.http.conn.routing.HttpRoute)
|
static int |
getMaxTotalConnections(HttpParams params) Deprecated. use ThreadSafeClientConnManager.getMaxTotal()
|
static long |
getTimeout(HttpParams params) Deprecated. use HttpConnectionParams.getConnectionTimeout(HttpParams)
|
static void |
setMaxConnectionsPerRoute(HttpParams params, ConnPerRoute connPerRoute) Deprecated. use ThreadSafeClientConnManager.setMaxForRoute(org.apache.http.conn.routing.HttpRoute, int)
|
static void |
setMaxTotalConnections(HttpParams params, int maxTotalConnections) Deprecated. use ThreadSafeClientConnManager.setMaxTotal(int)
|
static void |
setTimeout(HttpParams params, long timeout) Deprecated. use HttpConnectionParams.setConnectionTimeout(HttpParams, int)
|
相关推荐
例如,在HttpClient 3.x中,代码可能会使用`***mons.httpclient.HttpClient`类和`***mons.httpclient.methods.GetMethod`等,而在4.x版本中,这些都被新的API所替代。程序员需要熟悉`org.apache....
2013-11-21 15:31 292,890 httpclient-4.0.2.jar 2017-12-20 12:08 351,132 httpclient-4.1.1.jar 2012-08-03 01:45 451,595 httpclient-4.1.2-sources.jar 2012-08-03 01:44 352,254 httpclient-4.1.2.jar 2012-08-...
httpclient-4.5所需jar包,里面包含httpclient-...4.httpclient-4.5.jar 5.httpclient-cache-4.5.jar 6.httpclient-win-4.5.jar 7.httpcore-4.4.1.jar 8.httpmime-4.5.jar 9.jna-4.1.0.jar 10.jna-platform-4.1.0.jar
wechatpay-apache-httpclient-0.2.1.jar
httpclient-4.5.12.jar httpcore-4.4.13.jar为较新的版本 commons-beanutils-1.7.0.jar commons-collections-3.1.jar commons-httpclient-3.0.jar commons-httpclient-3.1-patched.jar commons-lang-2.5(1).jar ...
HttpClient 4.x版本引入了新的API,增强了性能和稳定性,同时也更加注重线程安全和资源管理。 最后,`httpcore-4.1.4.jar`是HttpClient的基础组件,它是Apache HttpComponents项目的一部分,主要负责HTTP协议的底层...
HttpClient 3.1是该库的一个旧版本,尽管现在已经被更新的HttpClient 4.x系列取代,但在很多老项目中仍然广泛使用。它允许开发者构建复杂的HTTP请求,比如POST、GET、PUT等,并可以处理各种HTTP响应。 2. **Apache ...
此外,它还允许自定义请求头,实现重试策略,以及支持连接池管理,以优化网络性能。HttpClient 4.4.1引入了一些bug修复和性能改进,以提高其稳定性和效率。 **httpcore-4.2-beta1.jar** Apache HttpCore是...
但是,使用HttpClient4.x时需要手动释放底层HTTP连接,否则将造成过高的资源占用。 在HttpClient4.x中,使用完后的HttpClient对象,需要显式地释放其使用的底层HTTP连接。如果不释放,将会导致系统资源的浪费,进而...
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods....
虽然`commons-httpclient-3.0.jar`是一个经典版本,但随着Java的发展,Apache社区已经推出了更现代的HttpClient 4.x系列,提供了更多改进和优化,如更好的线程安全、更丰富的API以及对HTTP/2的支持。因此,建议在新...
commons-beanutils-1.8.3 commons -codec-1.6 commons -collections-3.2.1 commons- lang-2.5.jar commons- longging-1.13.jar4.3.3.jar ezmorph-1.0.6.jar fluent-hc-4.3.3.jar gson-2.2.4.jar ...sqljdbc4.jar
httpclient-4.5.13-sources.jar
赠送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文档:...
3. 使用入门: - **创建HttpClient实例**:使用`HttpClientBuilder`构建器创建HttpClient对象,可以配置连接池大小、超时等参数。 - **构建HttpGet/HttpPost请求**:通过`HttpGet`或`HttpPost`构造HTTP请求,设置...
http://jakarta.apache.org/commons/httpclient/ org.apache.commons.httpclient.URI org.apache.commons.httpclient.Wire org.apache.commons.httpclient.Cookie org.apache.commons.httpclient.Header org.apache.commons...
此外,HTTPClient 4.x提供了更灵活的配置选项,比如连接管理器,允许自定义连接池大小、超时设置等。 1. **连接管理**:在HTTPClient 4.x中,`PoolingHttpClientConnectionManager`是默认的连接管理器,负责创建、...
HttpClient 4.5引入了`PoolingHttpClientConnectionManager`,它负责管理连接池,自动回收和复用连接。通过配置最大连接数、每个路由的最大连接数以及连接超时等参数,可以有效控制资源使用。 4. **异步编程支持**...
《Apache Commons HttpClient 3.1:HTTP客户端编程的基石》 ...然而,需要注意的是,HttpClient 3.1已不再维护,最新的稳定版本为HttpClient 4.x,对于新项目建议使用更现代的版本以获取更好的性能和兼容性。
httpclient-4.5.2.jar httpcore-4.4.4.jar httpmime-4.5.2.jar jackson-annotations-2.7.0.jar jackson-core-2.7.3.jar jackson-databind-2.7.3.jar jaxb-api-2.3.0.jar lz4-1.3.0.jar slf4j-api-1.7.21.jar csvjdbc...