一个有趣的遭遇:dubbo超时追踪出来的httpclient超时问题

开完早会,像往常一样打开我的SecureCRT,一个个点开线上的日志~惊!!!!全是bug:

一个有趣的遭遇:dubbo超时追踪出来的httpclient超时问题_第1张图片

按理说,dubbo大家都会配置retries参数,我配置的0;超时时间配置的200*1000ms
所以不存在二次请求;

reference id="outerInformationService" interface="com.dbn.remote.service.OuterInformationService" check="false" retries="0" timeout="200000"/>

反过来去看提供端,同样暴病:

一个有趣的遭遇:dubbo超时追踪出来的httpclient超时问题_第2张图片

大家看到这段错误,很明显,线程池中的100个线程不够用了,但是我这是一个刚刚搭建起来的项目,根本没有提供几个接口,怎么会无缘无故就线程不够用了呢?
排查:可以肯定的是,该接口所用时间超过了200 * 1000ms ,所以超时;开始排查程序问题;我的程序是一个爬虫,用来爬取一些数据,其中调用了四次http请求,使用了httpclient来做请求,发现没有设置超时时间,但心中想肯定有默认超时时间啊,就是这么自信,排查其它问题,结果排查完毕也没有找到原因;回过头再看看这个httpclient,点开源码,发现下面这段话:

  /**
     * Sets the socket timeout (SO_TIMEOUT) in milliseconds which is the 
     * timeout for waiting for data. A timeout value of zero is interpreted as an 
     * infinite timeout.
     *
     * @param newTimeoutInMilliseconds Timeout in milliseconds
     * 
     * @deprecated Use 
     * {@link org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)},
     * {@link HttpConnectionManager#getParams()}.
     *
     */
    public synchronized void setTimeout(int newTimeoutInMilliseconds) {
        this.params.setSoTimeout(newTimeoutInMilliseconds);
    }

真是太自信,这个socketTimeout的确有默认,默认是0,也就是永不超时,应该就是这个问题了,同样,在建立http请求的时候也需要设置超时时间:

   /**
     * Sets the timeout until a connection is etablished. A value of zero 
     * means the timeout is not used. The default value is zero.
     * 
     * @see HttpConnection#setConnectionTimeout(int)
     * @param newTimeoutInMilliseconds Timeout in milliseconds.
     * 
     * @deprecated Use 
     * {@link org.apache.commons.httpclient.params.HttpConnectionManagerParams#setConnectionTimeout(int)},
     * {@link HttpConnectionManager#getParams()}.
     */
    public synchronized void setConnectionTimeout(int newTimeoutInMilliseconds) {
       this.httpConnectionManager.getParams().setConnectionTimeout(newTimeoutInMilliseconds);
    }

同样默认参数是0,也就是永不超时,赶紧的,设置上去,我使用的是httpclient3.1,但是4.X的设置方式有所不同;

HttpClient client = new HttpClient();
                client.getHttpConnectionManager().getParams().setConnectionTimeout(CONNECTION_TIME_OUT);
                client.getHttpConnectionManager().getParams().setSoTimeout(WAITING_TIME_OUT);

问题发现:
这个爬虫爬取的网站是政府网站,所以极不稳定,之前正常运行了6个月,终于在今天暴露出了bug,谨记:在使用httpclient的时候记得设置超时时间,教训~!

你可能感兴趣的:(爬虫)