28

私は、Apache の HttpClient を多用する長期実行アプリケーションを開発しています。

私の最初のテスト実行では、アプリケーションは動かなくなるまで完全に機能しました。停止されず、例外もスローされず、何もせずにただそこに座っています。

たった今、2回目の走行をして時間を止めました。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());
}

httputil.getContentAsString()アプリケーションは、必要な URLを繰り返し呼び出します。

4

7 に答える 7

13

このコードは非推奨になりました (get 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);
于 2013-11-02T12:03:28.883 に答える
8

バージョン 4.4 の時点で、ユーザー user2393012 と Stephen C による両方の回答は廃止されました。別の方法があるかどうかはわかりませんが、私が行う方法は、ビルダー パラダイムである HTTPClientBuilder を使用することです。

元。

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

OPが言及したものと非常によく似た(実際にはOPの問題だった可能性があります)問題も発生しますが、Apacheがデフォルトの同時接続をクライアントごとに2つの接続のみに設定しているためです。これに対する解決策は、最大接続数を増やすか、可能であればそれらを閉じることです。

最大接続数を増やすには:

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

接続を閉じるには、BasicHttpClientConnectionManager を使用して、close メソッドを呼び出すことができます。

于 2015-06-25T05:04:33.667 に答える
6

使用しているHttpClientのバージョンはまだわかりませんが、バージョン4であると想定して、このブログ記事で何をすべきかを説明しています。

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeoutMillis);
HttpConnectionParams.setSoTimeout(httpParams, socketTimeoutMillis);
于 2012-03-29T12:25:14.827 に答える
4

私は同じ問題を抱えていました.DefaultHttpClientを閉じなかったためにスタックしました.
したがって、これは間違っています:

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

そして、これは正しいです:

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

それが誰かを助けることを願っています。

于 2015-08-27T13:43:44.370 に答える
3

デフォルトでは、HttpClient はタイムアウトしません (これは、役立つどころか、より多くの問題を引き起こします)。あなたが説明しているのはハードウェアの問題である可能性があります。ネットワーク アダプターが停止すると、HttpClient がハングします。

DefaultHttpClientへのコンストラクターの一部としてHttpParams設定されるパラメーターは次のとおりです。

http.socket.timeout : ミリ秒単位でソケット タイムアウト (SO_TIMEOUT) を定義します。これは、データを待機するためのタイムアウト、または別の言い方をすれば、2 つの連続するデータ パケット間の最大非アクティブ期間です)。ゼロのタイムアウト値は、無限のタイムアウトとして解釈されます。このパラメーターは、タイプ java.lang.Integer の値を想定しています。このパラメーターが設定されていない場合、読み取り操作はタイムアウトしません (無限のタイムアウト)。

これにより、接続にタイムアウトが設定されるため、設定されたタイムアウトの後に例外がスローされます。

于 2012-03-29T12:33:01.223 に答える