簡體   English   中英

HttpClient沒有任何異常

[英]HttpClient stuck without any exception

我正在開發一個長期運行的應用程序,該應用程序大量使用來自apache的HttpClient。

在我的第一次測試運行中,應用程序運行良好,直到它被卡住。 它沒有停止,它沒有拋出任何異常,只是坐在那里什么都不做。

我剛剛做了第二次跑步並停止了時間,並在大約停止后停止了。 24小時不間斷運行。 此外,我注意到我運行它的筆記本電腦的互聯網連接在應用程序卡住的確切時刻終止。 我不得不重啟我的WLAN適配器,以便再次運行網絡。

但是,應用程序在連接再次啟動后沒有返回工作狀態。 現在,它又被卡住了。

在HttpClient中是否有任何超時控制器我都不知道? 為什么我的應用程序在連接斷開時不會拋出異常?

使用客戶端的部分如下所示;

public HttpUtil(ConfigUtil config) {
    this.config = config;

    client = new DefaultHttpClient();
    client.getParams().setParameter(HttpProtocolParams.USER_AGENT, this.config.getProperty("httputil.userAgent"));
}

public String getContentAsString(String url) throws ParseException, ClientProtocolException, IOException {
    return EntityUtils.toString(
            client.execute(
                    new HttpGet(url)).getEntity());
}

應用程序重復調用它所需的URL上的httputil.getContentAsString()

此代碼現已棄用(獲取HttpParams等)。 更好的方法是:

RequestConfig defaultRequestConfig = RequestConfig.custom()
    .setCookieSpec(CookieSpecs.BEST_MATCH)
    .setExpectContinueEnabled(true)
    .setStaleConnectionCheckEnabled(true)
    .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
    .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
    .build();

HttpGet httpGet = new HttpGet(url);    
RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
    .setSocketTimeout(5000)
    .setConnectTimeout(5000)
    .setConnectionRequestTimeout(5000)
    .build();
httpGet.setConfig(requestConfig);

從版本4.4開始,用戶user2393012和Stephen C的兩個答案都已被棄用。 我不確定是否有其他方法可以做到,但我這樣做的方法是使用構建器范例HTTPClientBuilder。

防爆。

HttpClients.custom().setConnectionTimeToLive(1, TimeUnit.MINUTES).build()

OP提到的問題也非常類似(實際上可能是OP問題),但是由於Apache將默認並發連接設置為每個客戶端只有兩個連接。 對此的解決方案是增加最大連接數或關閉它們(如果可以)。

要增加最大連接數:

HttpClients.custom().setMaxConnPerRoute(100000).build()

要關閉連接,可以使用BasicHttpClientConnectionManager並調用close方法

您還沒有說過您使用的是哪個版本的HttpClient,但假設它是版本4, 這篇博客文章解釋了該怎么做。

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeoutMillis);
HttpConnectionParams.setSoTimeout(httpParams, socketTimeoutMillis);

我在另一個線程中給出了類似的答案( HttpClient在socketRead0上掛起並成功執行了方法

在我的例子中,我在請求中設置了connectionTimeout和socketTimeout,但是在建立SSL連接期間沒有使用連接套接字。 因此,我有時會在SSL握手期間掛起。 下面是一些使用v4.4設置所有3個超時的代碼(也在v4.5中測試過)

// Configure the socket timeout for the connection, incl. ssl tunneling
connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(200);
connManager.setDefaultMaxPerRoute(100);

SocketConfig sc = SocketConfig.custom()
    .setSoTimeout(soTimeoutMs)
    .build();

connManager.setDefaultSocketConfig(sc);

HttpClient client = HttpClients.custom()
            .setConnectionManager(connManager)
            .setConnectionManagerShared(true)
            .build();

// configure the timeouts (socket and connection) for the request
RequestConfig.Builder config = = RequestConfig.copy(RequestConfig.DEFAULT);
config.setConnectionRequestTimeout(connectionTimeoutMs);
config.setSocketTimeout(socketTimeoutMs);

HttpRequestBase req = new HttpGet(uri);
req.setConfig(config.build());

client.execute(req);

我所有的超時設置都很好,但我發現我們在url上做了http分塊但沒有發送任何結果(在chrome中工作正常,但在http客戶端它甚至掛起,即使設置了超時)。 幸運的是,我擁有服務器,只是返回一些垃圾,它不再掛起。 這似乎是一個非常獨特的錯誤,http客戶端不能很好地處理某種空的分塊情況(雖然我可能會離開)....我只是知道它每次掛在同一個網址上的空數據和該網址是http chunking csv下載回我們的http客戶端。

我有同樣的問題,因為我沒有關閉DefaultHttpClient而卡住了。
所以這是錯的:

try{
    DefaultHttpClient httpclient = new DefaultHttpClient();
    ...
} catch (Exception e){
    e.PrintStackTrace();
}

這是對的:

try (DefaultHttpClient httpclient = new DefaultHttpClient()){
    ...
} catch (Exception e){
    e.PrintStackTrace();
}

希望它可以幫助某人。

默認情況下,HttpClient不會超時(這會導致更多問題)。 您所描述的可能是硬件問題,如果您的網絡適配器死亡,HttpClient將掛起。

以下是設置為HttpParams參數 ,作為DefaultHttpClient的構造函數的一部分,包括

http.socket.timeout :以毫秒為單位定義套接字超時(SO_TIMEOUT),這是等待數據的超時, 換句話說 ,兩個連續數據包之間的最大周期不活動。 超時值為零被解釋為無限超時。 此參數需要java.lang.Integer類型的值。 如果未設置此參數,則讀取操作不會超時(無限超時)。

這將在連接上設置超時,因此在設置超時后將拋出異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM