zoukankan      html  css  js  c++  java
  • httpclient httpclient使用连接池

    httpclient使用连接池

    http协议是无状态的,但毕竟是基于tcp的,底层还是需要和服务器连接的,
    对于需要从同一个站点抓取大量网页的程序,应该使用连接池,否则每次抓取都和web站点建立连接,发送请求,获得响应,释放连接.
    一方面效率不高
    一方面不小心就会疏忽某些资源的释放,导致站点拒绝连接(很多站点会拒绝大量连接,防止Dos攻击)
    

    httpclient连接池

    httpclient从4.2版本开始抛弃了先前的
    SingleClientClientConnManger和ThreadSafeConnManger取而代之的是BasicClientConnectionManger和PoolingClientConnectionManager
    BasicClientConnectionManager
    该类内部只维护了一个活动的connection,尽管这个类是线程安全的,但是最好在一个单独的线程中重复使用它。
    如果在同一个BasicClientConnectionManager对象中,
    * 多次请求与先前请求时同一个route,那么BasicClientConnectManager会使用同一个连接完成后续请求,
    *否则,BasicClientConnectionManager会将先前的connection关闭,然后为后续请求创建一个新的连接。
    也就是说BasicClientConnectionManager会尽量使用同一个BasicClientConnectionManager完成
    PoolClientConnectionManager
    该类可以在多个线程中使用,连接按照route被缓存(pooled),当后续请求route请求已经在pool中存在,就会使用pool中先前使用的connection获取请求。
    PoolClientonnectionManager对每个route维护的connection数目有上限要求,
    默认每个route最多维护两个并发线程的connection连接,
    整个pool最多容纳20个并发connection。(可以通过设置来修改这些限制)
    

    BasicClientConnectionManager

    public static void basicClientTest() throws Exception{
      HttpClient httpclient = new DefaultHttpClient();
      HttpGet httpGet = new HttpGet("http://m.weather.com.cn/data/101010100.html");
      HttpResponse response=httpClient.execute(httpGet);
      String result = EntityUtils.toString(response.getEntity(),charset.forName("utf-8"));
      System.out.println(result);
      httpClient.getConnectionManager().shutdowm();
    }
    PoolingClientConnectionManager
    SchemeRegistry schemeRegistry = new SChemeRegistry();
    schemeRegistry.register(new Scheme("http",80,PlainSocketFactory.getSocketFactory()));
    schemeRegistry.register(new Scheme("https",443,SSLSocketFactory.getSocketFactory()));
    ​
    HttpHost baidu = new HttpHost("www.baidu.com",80);
    HttpHost local = new HttpHost("127.0.0.1",8090);
    ​
    PoolingClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);
    cm.setMaxPerRoute(new HttpRoute(baidu),30);
    cm.setMaxPerRoute(new HttpRoute(local),50);
    

    连接池使用总结

    1) 首先配置最大连接数和最大路由连接数,如果连接的url只有一个,两个必须配置成一样,否则只会去最小值
    (默认最大连接数是20,每个路由最大连接是2)
    ​
    2) 最好配置httpclient的等待时间和响应时间.否则就会一直等待
    HttpParams httpparams = new BasicHttpParams();
    httpparams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,CONNECT_TIMEOUT);
    httpparams.setParameter(CoreConnectionPNames.SO_TIMEOUT,READ_TIMEOUT);
    ​
    3) httpClient必须releaseConnection,但不是abort。因为releaseconnection是归还连接到到连接池,而abort是直接抛弃这个连接,
    而且占用连接池的数目。
    HttpGet httpget = new HttpGet(url);
    httpGet.releaseConnection();
    ​
    4) httpclient设置的最大连接数绝对不能操作tomcat设置的最大连接数,否则tomcat的连接就会被httpclient连接池一直占用,直到系统挂掉。
    ​
    5) 可以使用tomcat的长连接和httpclient连接池和合理使用来增加系统响应速度
    cm.setMaxTotal(200);//创建socket的上线是200
    cm.setDefaultMaxPerRoute(20);//默认对每个指定连接的服务器(指定的ip)可以创建并发20socket进行访问
    
  • 相关阅读:
    遇到的函数知识
    网络编程
    python中的并发编程
    Django contenttypes组件
    同源策略定义及跨域解决方案
    Django Rest framework
    RESTful API
    python 给对象添加方法
    python 装饰器(复杂一点的)
    android动态替换Fragment向下传递数据
  • 原文地址:https://www.cnblogs.com/ssgao/p/8829275.html
Copyright © 2011-2022 走看看