8

私たちの Web アプリケーションでは、ユーザーは URL を送信できます。データを取得し、サーバー側で解析します。リクエストごとに、次の(関連する)設定で HttpClient を使用します

connectionManager.getParams().setConnectionTimeout(10000);
connectionManager.getParams().setSoTimeout(10000);

HttpMethod.getResponseBody を呼び出すと、ステータス コードは既にチェックされており、受け入れ可能です。この時点で、スレッドは次のスタック トレースでハングします。

java.net.SocketInputStream.socketRead0 ( native code )
java.net.SocketInputStream.read ( SocketInputStream.java:150 )
java.net.SocketInputStream.read ( SocketInputStream.java:121 )
java.io.BufferedInputStream.read1 ( BufferedInputStream.java:273 )
java.io.BufferedInputStream.read ( BufferedInputStream.java:334 )
java.io.FilterInputStream.read ( FilterInputStream.java:133 )
org.apache.commons.httpclient.AutoCloseInputStream.read ( AutoCloseInputStream.java:108 )
java.io.FilterInputStream.read ( FilterInputStream.java:107 )
org.apache.commons.httpclient.AutoCloseInputStream.read ( AutoCloseInputStream.java:127 )
org.apache.commons.httpclient.HttpMethodBase.getResponseBody ( HttpMethodBase.java:690 )

これが発生した正確な URL を見つけることができず (ライブ環境でのインシデントでした)、それを再現することもできませんでした。接続しているサーバーの動作がおかしいだけだと思いたいのですが、何かが足りないのかもしれません。どちらの場合でも、ブロッキング メソッドの呼び出しが永久に待機しないようにする方法はありますか? SoTimeout はソケット読み取りタイムアウトでもありますか? 私が見逃している別の設定はありますか?

4

5 に答える 5

0

HttpClient は接続とリクエストを区別します。setSoTimeoutは接続ソケットのタイムアウトをsetConnectionTimeout構成し、接続マネージャー (接続を待機する時間) と接続自体の確立の両方のタイムアウトを構成します。あなたが提供したコードでは、リクエスト自体に使用されるソケットのタイムアウトを設定していません。残念ながら、HttpClient にはデフォルトでタイムアウトがありません。

v4.4.1での方法は次のとおりです。

// 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);
于 2016-01-04T18:59:46.837 に答える
0

https://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/apache/http/client/methods/HttpUriRequest.htmlを参照してください。 #abort%28%29 . ただし、インターセプトを必要としないタイムアウトを設定する方が適切です。関連する質問は次のとおりです。Apache httpクライアントでタイムアウトを設定する

于 2014-04-24T09:38:46.177 に答える
0

HttpMethod.getResponseBody を呼び出すと、ステータス コードは既にチェックされており、受け入れ可能です。この時点で、スレッドはハングアップします

呼び出しの同期に問題があるようです...メソッドを確実にする必要があります

HttpMethod.getResponseBody

ステータスコードを変更する部分は順番に呼び出されるかミューテックス(セマフォ)を使用する必要があります

また、ハングを防ぐためにタイムアウト制限を減らす必要があります。

于 2013-04-08T08:59:28.797 に答える