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

http连接池使用 参数

    博客分类:
  • java
 
阅读更多

在一次服务器异常的排查过程当中(服务器异常排查的过程我会另起文章),我们决定使用HttpClient4.X替代HttpClient3.X或者HttpConnection。

 

为什么使用HttpClient4?主要是HttpConnection没有连接池的概念,多少次请求就会建立多少个IO,在访问量巨大的情况下服务器的IO可能会耗尽。

 

HttpClient3也有连接池的东西在里头,使用MultiThreadedHttpConnectionManager,大致过程如下:

 

  1. MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();  
  2. HttpClient client = new HttpClient(connectionManager);...// 在某个线程中。  
  3. GetMethod get = new GetMethod("http://jakarta.apache.org/");  
  4. try {  
  5. client.executeMethod(get);// print response to stdout  
  6. System.out.println(get.getResponseBodyAsStream());  
  7. finally {  
  8. // be sure the connection is released back to the connection   
  9. managerget.releaseConnection();  
  10. }  

 

可以看出来,它的方式与jdbc连接池的使用方式相近,我觉得比较不爽的就是需要手动调用releaseConnection去释放连接。对每一个HttpClient.executeMethod须有一个method.releaseConnection()与之匹配。

 

 

 

HttpClient4在这点上做了改进,使用我们常用的InputStream.close()来确认连接关闭(4.1版本之前使用entity.consumeContent()来确认内容已经被消耗关闭连接)。具体方式如下:

 

  1. ...HttpClient client = null;InputStream in = null;  
  2. try{  
  3. client = HttpConnectionManager.getHttpClient();  
  4. HttpGet get = new HttpGet();  
  5. get.setURI(new URI(urlPath));  
  6. HttpResponse response = client.execute(get);  
  7. HttpEntity entity =response.getEntity();  
  8. if( entity != null ){   
  9.  in = entity.getContent();  
  10.  ....  
  11. }catch (Exception e){  
  12. ....  
  13. }finally{  
  14. if (in != null){  
  15. try{in.close ();}catch (IOException e){  
  16. e.printStackTrace ();  
  17. }  
  18. }  
  19. }  

 

2012-03-06更新:

 

有网友提出调用in.close()是否会关闭底层socket,事情是这样的:

 

  1. 回复kangkang203:感谢你提出的这个问题。  
  2. 首 先我文中提出的方法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的关闭。  
  3. 另外,由于http本身我们把它当做“短连接”,所以在一次请求交互完成后仍然打开socket的意义不是很大,毕竟它不像长连接那样在一个连接建立之后会有很多次数据交互。我们试用连接管理器的更多意义在于它对连接的管理。  


 

好说完了连接池的使用流程,现在来说一说连接池在使用时最重要的几个参数。我用4.1的版本实现了一个简单的HttpConnectionManager,代码如下:

 

 

 

  1. public class HttpConnectionManager {   
  2.   
  3.     private static HttpParams httpParams;  
  4.     private static ClientConnectionManager connectionManager;  
  5.   
  6.     /** 
  7.      * 最大连接数 
  8.      */  
  9.     public final static int MAX_TOTAL_CONNECTIONS = 800;  
  10.     /** 
  11.      * 获取连接的最大等待时间 
  12.      */  
  13.     public final static int WAIT_TIMEOUT = 60000;  
  14.     /** 
  15.      * 每个路由最大连接数 
  16.      */  
  17.     public final static int MAX_ROUTE_CONNECTIONS = 400;  
  18.     /** 
  19.      * 连接超时时间 
  20.      */  
  21.     public final static int CONNECT_TIMEOUT = 10000;  
  22.     /** 
  23.      * 读取超时时间 
  24.      */  
  25.     public final static int READ_TIMEOUT = 10000;  
  26.   
  27.     static {  
  28.         httpParams = new BasicHttpParams();  
  29.         // 设置最大连接数  
  30.         ConnManagerParams.setMaxTotalConnections(httpParams, MAX_TOTAL_CONNECTIONS);  
  31.         // 设置获取连接的最大等待时间  
  32.         ConnManagerParams.setTimeout(httpParams, WAIT_TIMEOUT);  
  33.         // 设置每个路由最大连接数  
  34.         ConnPerRouteBean connPerRoute = new ConnPerRouteBean(MAX_ROUTE_CONNECTIONS);  
  35.         ConnManagerParams.setMaxConnectionsPerRoute(httpParams,connPerRoute);  
  36.         // 设置连接超时时间  
  37.         HttpConnectionParams.setConnectionTimeout(httpParams, CONNECT_TIMEOUT);  
  38.         // 设置读取超时时间  
  39.         HttpConnectionParams.setSoTimeout(httpParams, READ_TIMEOUT);  
  40.   
  41.         SchemeRegistry registry = new SchemeRegistry();  
  42.         registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));  
  43.         registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));  
  44.   
  45.         connectionManager = new ThreadSafeClientConnManager(httpParams, registry);  
  46.     }  
  47.   
  48.     public static HttpClient getHttpClient() {  
  49.         return new DefaultHttpClient(connectionManager, httpParams);  
  50.     }  
  51.   
  52. }  

 

最大连接数、获取连接的最大等待时间、读取超时时间 这些配置应该比较容易理解,一般的连接池都会有这些配置,比较特别的是 每个路由(route)最大连接数

 

 

 

什么是一个route?

 

 

 

这里route的概念可以理解为 运行环境机器 到 目标机器的一条线路。举例来说,我们使用HttpClient的实现来分别请求 www.baidu.com 的资源和 www.bing.com 的资源那么他就会产生两个route。

 

 

 

这里为什么要特别提到route最大连接数这个参数呢,因为这个参数的默认值为2,如果 不设置这个参数值默认情况下对于同一个目标机器的最大并发连接只有2个!这意味着如果你正在执行一个针对某一台目标机器的抓取任务的时候,哪怕你设置连接 池的最大连接数为200,但是实际上还是只有2个连接在工作,其他剩余的198个连接都在等待,都是为别的目标机器服务的。

 

 

 

怎么样蛋疼吧,我是已经有过血的教训了,在切换到HttpClient4.1的起初没有注意到这个配置,最后使得服务承受的压力反而不如从前了,所以在这里特别提醒大家注意。

 

 

 

HttpClient4.X 教程下载:

 

http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient-contrib/docs/translated-tutorial/httpclient-tutorial-simplified-chinese.pdf

 

 

 

关于版本的补充:

 

网友w2449008821提醒之后我才发现在HttpClient4.1+的版本ConnManagerParams已经被Deprecated了。

 

我在写这篇日志的时候时候的httpclient 版本是4.0.3,从4.0版本之后ConnManagerParams被Deprecated,没想到一个小版本升级会有这么大变化。

 

官网教程举例了新的连接池设置:

 

 

 

  1. SchemeRegistry schemeRegistry = new SchemeRegistry();  
  2. schemeRegistry.register(  
  3.          new Scheme("http"80, PlainSocketFactory.getSocketFactory()));  
  4. schemeRegistry.register(  
  5.          new Scheme("https"443, SSLSocketFactory.getSocketFactory()));  
  6.   
  7. ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry);  
  8. // Increase max total connection to 200  
  9. cm.setMaxTotalConnections(200);  
  10. // Increase default max connection per route to 20  
  11. cm.setDefaultMaxPerRoute(20);  
  12. // Increase max connections for localhost:80 to 50  
  13. HttpHost localhost = new HttpHost("locahost"80);  
  14. cm.setMaxForRoute(new HttpRoute(localhost), 50);  
  15.    
  16. 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)


参考:http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/params/ConnManagerParams.html

http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e638

 

 

 

http://blog.csdn.net/shootyou/article/details/6415248

分享到:
评论

相关推荐

    okhttp中连接池实现

    如果一个连接长时间未使用或者服务器已经关闭了连接,OkHttp会将其从连接池中移除,防止资源浪费。 3. **连接池的大小限制**:为了防止过多的连接占用系统资源,OkHttp为每个主机名设定了连接数量的最大值。超出这...

    Tomcat6配置连接池

    ### Tomcat6配置连接池详解 #### 一、引言 在Java Web开发中,数据库连接池技术的应用极为广泛。合理的数据库连接管理不仅能提高应用程序的性能,还能有效避免因频繁创建销毁连接所导致的资源浪费问题。Apache ...

    连接池 连接池连接池 连接池

    在JSP中使用连接池,通常是在Servlet或者Filter中初始化连接池,然后在需要访问数据库的JSP页面或Servlet中获取和释放连接。这种方式使得数据库连接的管理更加规范,降低了资源消耗。 连接池的使用还有以下几个重要...

    HttpCient连接池Demo

    创建HttpClient实例时,我们需要设置连接池参数。`PoolingHttpClientConnectionManager`是HttpClient的连接池管理器,它可以管理连接的创建、复用和关闭。我们可以通过`PoolingHttpClientConnectionManager....

    BIO Socket连接池

    同时,这也为我们提供了优化和定制网络通信的基础,比如调整连接池参数,实现更高效的并发模型等。 在实际开发中,我们还可以考虑使用NIO(非阻塞I/O)或AIO(异步I/O)模型来进一步提升性能,但这些都需要更复杂的...

    websphare配置数据库连接池

    SQL Server 连接池的配置步骤与 Oracle 相似,具体的参数值为: * JDBC 提供程序:下拉选择 Microsoft JDBC driver for MSSQLServer 2000 * 数据源的 JNDI 名称为 SQLSERVER_JNDI * URL 的值为 jdbc:microsoft:sql...

    proxool连接池jar包

    2. **易用性**:配置简单,通过XML配置文件即可轻松设置连接池参数,如最大连接数、最小连接数、超时时间等。 3. **监控功能**:独特的监控机制使得开发者可以实时查看连接池的状态,如当前连接数、空闲连接数、...

    weblogic数据源连接池

    4. 配置连接池参数:在数据源配置页面,可以设置连接池的大小,如最小连接数、最大连接数、初始连接数等。此外,还可以配置连接超时、空闲连接存活时间等参数,以优化连接池的使用效率。 5. 配置JNDI名称:为数据源...

    数据库连接池-连接的关闭内幕

    例如,在Apache Commons DBCP中,可以通过设置`minIdle`和`maxIdle`参数来控制连接池中空闲连接的数量。当连接池中的空闲连接达到最小值时,即使没有新的连接请求,也会维持一定数量的连接处于空闲状态,以备后续...

    weblogic配置sql数据连接池

    3. 配置连接池参数:在创建的数据源配置页面,找到“连接池”部分,这里可以设置以下关键参数: - 最小连接数:定义连接池最小保持的连接数量,即使没有活动的连接,也会保留这个数量。 - 最大连接数:定义连接池...

    Tomcat连接池配置详解

    在高并发和大数据量的场景下,为了提高应用性能和资源利用率,使用连接池是必不可少的策略。Tomcat连接池,也称为数据源(DataSource),允许复用已建立的数据库连接,减少创建和关闭连接的开销。 配置Tomcat连接池...

    sql连接池配置文件

    在Java开发中,数据库连接管理是一项关键任务,为了提高应用程序的性能和资源利用率,我们通常会使用SQL连接池。连接池允许程序重复使用已建立的数据库连接,避免频繁创建和销毁连接带来的开销。本篇文章将详细介绍...

    构建高效的python requests长连接池详解

    1. **限制连接池大小**:可以通过设置`max_connections`参数限制每个主机的并发连接数,以避免资源浪费。 ```python from requests.adapters import HTTPAdapter s = requests.Session() s.mount('http://', ...

    proxool数据库连接池实例(带监控功能)

    本文将详细介绍Proxool数据库连接池及其监控功能,通过一个实际的实例来展示其工作原理和使用方法。 Proxool是Apache软件基金会的一个开源项目,它提供了一个轻量级、高性能的数据库连接池解决方案。Proxool与其他...

    JMeter测试有无数据库连接池的性能

    - 优化可能涉及调整数据库连接池参数,如最大连接数、最小连接数、超时设置等,以达到最佳性能和资源利用。 综上所述,"JMeter测试有无数据库连接池的性能"这个话题探讨的是如何利用JMeter这一工具来衡量数据库...

    c3p0数据库连接池

    - 根据应用的并发量和数据库负载,合理设置连接池参数,避免资源浪费或连接不足。 - 定期监控连接池状态,及时调整配置,防止异常情况。 - 开启连接验证,确保从连接池获取的连接始终可用。 - 注意数据库驱动...

    数据库 连接池

    1. **初始化**:在应用程序启动时,数据库连接池会根据配置文件中的参数创建一定数量的空闲连接,并将这些连接放置到连接池中。 2. **获取连接**:当应用程序需要访问数据库时,会首先从连接池中获取一个空闲的...

    was配置db2数据连接池

    - 在生产环境中,你应该定期监控连接池的使用情况,根据性能和负载调整连接池参数,以达到最佳性能。 以上步骤提供了配置DB2连接池的基本指南,但具体的配置可能会因为WAS版本和DB2版本的不同而略有差异。请务必...

    Java Web开发的连接池集

    在Java Web开发中,连接池是一种管理数据库连接的机制,旨在提高应用程序的性能和效率。连接池通过预先创建并维护...在实际项目中,开发者还需要关注如何正确配置和优化连接池参数,以适应不同的负载情况和性能需求。

Global site tag (gtag.js) - Google Analytics