一個有趣的遭遇:dubbo超時追蹤出來的httpclient超時問題

開完早會,像往常一樣打開我的SecureCRT,一個個點開線上的日誌~驚!!!!全是bug:

dubbo超時了

按理說,dubbo大家都會配置retries參數,我配置的0;超時時間配置的200*1000ms
所以不存在二次請求;

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

反過來去看提供端,同樣暴病:

提供端配置的線程被消耗完了

大家看到這段錯誤,很明顯,線程池中的100個線程不夠用了,但是我這是一個剛剛搭建起來的項目,根本沒有提供幾個接口,怎麼會無緣無故就線程不夠用了呢?
排查:可以肯定的是,該接口所用時間超過了200 * 1000ms ,所以超時;開始排查程序問題;我的程序是一個爬蟲,用來爬取一些數據,其中調用了四次http請求,使用了httpclient來做請求,發現沒有設置超時時間,但心中想肯定有默認超時時間啊,就是這麼自信,排查其它問題,結果排查完畢也沒有找到原因;回過頭再看看這個httpclient,點開源碼,發現下面這段話:

  /**
     * Sets the socket timeout (<tt>SO_TIMEOUT</tt>) 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的時候記得設置超時時間,教訓~!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章