美文网首页
记一次工作中的重大BUG---http连接池

记一次工作中的重大BUG---http连接池

作者: jarvan4dev | 来源:发表于2016-05-10 00:26 被阅读4226次

很晚了,但是还是决定打开电脑记录下最近一段时间遇到的问题。
事情是这样的,前段时间公司一个同事ZM休婚假,我就接手了他手上的一家比较重要的保险公司(暂时成为RB吧,我们是一家保险销售平台,上海最会保),其实一开始我是拒绝的,因为这家公司实际上的流程不是正常的,因为它是爬取的,而且据说有很多坑(事后发现并不是那样夸张吧)。

说爬取,其实也就是用httpClient模拟浏览器的行为,然后用htmlParse解析xml,然后在模拟提交表单之类。我在程序入口处将要访问的链接log一下,用浏览器去访问这个链接直接能够打开,但是httpClient却经常抛socketTimeoutException,这就奇怪了,难道是cookie有问题?RB服务器没有检测到所需要的cookie?然后这个http connect就一直被idle了?但是我是访问RB的第一个链接啊,明显不需要任何cookie啊,第一个猜想被pass掉;好吧,继续猜想!难道是没有完全模拟浏览器?为此做了如下httpHeader设置:

private void setHttpHeader(HttpMethod method, String referSuffix, boolean isAjax){   
    method.setRequestHeader("Accept", "text/html, */*; q=0.01");    
    method.setRequestHeader("Accept-Encoding", "gzip, deflate");
    method.setRequestHeader("Accept-Language","zh-CN,zh;q=0.8,en;q=0.6");
    method.setRequestHeader("Cache-Control", "no-cache");
    method.setRequestHeader("Connection", "Keep-Alive");
    method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
    method.setRequestHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36");
    method.setRequestHeader("Host", "www.epicc.com.cn");
    method.setRequestHeader("Referer", BASE_URL + referSuffix);
    method.setRequestHeader("Origin","http://www.epicc.com.cn");
    if (isAjax){
        method.setRequestHeader("X-Requested-With", "XMLHttpRequest");
    }
}

每次构造get或者post的时候调用此方法来设置头,然而并没有啥用处,依然socketTimeoutException;
然后我就蒙圈了,各种想,然而并没有什么头绪!其实我当时想的是我应该用log4j打印一下httpClient的debug的log的,或许能够找到原因;
另一个同事WL先tcpdump抓了包,ZM和WL工作8年的老程序员,果然还是经验很重要,然后就分析出来了,分析发现正常情况下,http发送前都需要进行tcp握手建立连接,然后再http发送报文,然而使用了连接池后,每次http请求结束后,这些连接会被放回连接池,直到下次被使用,但是我们不知道的是,可能这个时候服务器已经把这个连接断开了,而第二次如果有请求发现连接池中有连接空闲,就未经检查就使用了这个connection,这样无法发送报文,就好抛出socketTimeoutException,这就是为什么有时候会socketTimeout,有时候不会,因为这个connection不知道有没有被服务器shutdown掉,如果关闭了,则异常呗!

如何使用?

MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams params = connectionManager.getParams();
params.setConnectionTimeout(30000);
params.setSoTimeout(60000);
params.setDefaultMaxConnectionsPerHost(1000);
params.setMaxTotalConnections(1000);
httpClient = new HttpClient(connectionManager);

当初使用MultiThreadedHttpConnectionManage(关于)是为了复用连接的连接,解决办法就是不用连接池了呗,每个service实例中都存有一个共享的httpClient,这样多次发起http请求也可以公用这个httpClient;

当然最好的解决办法或者说是使用MultiThreadedHttpConnectionManage的错误是由于没有设置正确的参数,HttpConnectionParams中有一个方法:

/**
   * Defines whether stale connection check is to be used. Disabling
   * stale connection check may result in slight performance improvement
   * at the risk of getting an I/O error when executing a request over a
   * connection that has been closed at the server side.
   * @param value <tt>true</tt> if stale connection check is to be used,
   * <tt>false</tt> otherwise.
   */
   public void setStaleCheckingEnabled(boolean value) {
      setBooleanParameter(STALE_CONNECTION_CHECK, value);
   }

设置true后每次使用连接池中的链接会先检查下链接是否可用;虽然可能会消耗15-30ms,但是这个应该比tcp握手来的快。

其实任然还有很多优化的地方,如失败重试等等;

另外整理了一下HTTP Client MultiThreadedHttpConnectionManager线程安全连接管理类源码解析
请看:

相关文章

  • 记一次工作中的重大BUG---http连接池

    很晚了,但是还是决定打开电脑记录下最近一段时间遇到的问题。事情是这样的,前段时间公司一个同事ZM休婚假,我就接手了...

  • 记一次重大bug

    新工作开始没多久新版发布弄出个重大BUG,以此篇日志引以为戒。1.对每一行代码都不能掉以轻心,可能你的一个小问题会...

  • 记一次重大的录制事故

    今天是胆战心惊的一天。 早上去演播室录节目,因为昨天和嘉宾提前对了稿件。所以在录制的时候,嘉宾发挥的特别好,录制十...

  • 记一次“重大”实习事故

    关于我实习的背景信息请移步关于我在宾大读心理咨询的二三事查看,这里不做赘述。 事故发生一周了,本来打算事情完全解决...

  • 撩课-JavaWeb之什么是连接池与连接池使用

    什么是连接池 没有连接池的情况 数据库连接池 池 连接池 作用 数据库连接池 示意图 连接池中的属性 连接池使用 ...

  • 07-Redis 管道

    Redis 管道 redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如...

  • JDBC 进阶——连接池

    本文包括传统JDBC的缺点连接池原理自定义连接池开源数据库连接池DBCP连接池C3P0连接池Tomcat内置连接池...

  • 代码分析

    interface 相关配置 默认子连接池 定义全局连接池 注册连接池 默认子连接池 连接

  • 记一次Jedis连接池泄漏的分析

    1. 背景 随着业务的快速发展,公司使用redis cluster+本地缓存的模式来化解大流量下对系统的冲击。re...

  • js异常错误处理

    记一次最近工作中遇到问题的处理方法。整理自https://www.cnblogs.com/luluping/arc...

网友评论

      本文标题:记一次工作中的重大BUG---http连接池

      本文链接:https://www.haomeiwen.com/subject/zdwerttx.html