質問

私たちは、多くの場合、同じプロバイダ(集約ユースケースの一種)にREST APIを呼び出すためのHttpURLConnection APIを使用しています。我々は、プロバイダのホスト(常に同じIP)に常に開い5つの接続のプールを維持したい。

適切な解決策とは何ですか?ここでは試したものです。


System.setProperty("http.maxConnections", 5);  // set globally only once
...
// everytime we need a connection, we use the following
HttpURLConnection conn = (HttpURLConnection) (new URL(url)).openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setUseCaches(true);
...
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
...
BufferedReaderのは、これ以上のバイトを返すまで、

は、この時点では、入力ストリームを読み込みます。我々は、プロバイダへの根本的な接続を再利用したい場合は、私たちは、その点の後に何をしますか?私たちは、入力ストリームが完全に読まれている場合、接続は、プールに戻って追加されたという印象の下にあった。

これは、数週間のためにこのように作業していて、今日では、この例外を生成する動作を停止されています:java.net.SocketException: Too many open files

私たちは(lsofを実行することで)このようなCLOSE_WAIT状態で多数のソケットを見つけました: java 1814 root 97u IPv6 844702 TCP colinux:58517->123.123.254.205:www (CLOSE_WAIT)

のいずれかconn.getInputStream()。近い()またはconn.disconnect()が完全に接続を閉じ、プールから削除していないのでしょうか?

他のヒント

参照するは、引用されました勘当で本当に役立ったものだった。

私たちは、Apache HttpClientをよりよく知っているが、それは別のjarファイルを必要とし、我々はアプレットでこのコードを使用する場合があります。

の呼び出しHttpURLConnection.connect()は不要でした。私はそれが接続の再利用を防ぐかはわからないが、我々はそれを取り出しました。ストリームをクローズしても安全ですが、接続にdisconnect()を呼び出すと、再利用を防ぐことができます。また、sun.net.http.errorstream.enableBuffering=trueを設定することができます。

ここでは、私たちが使用して終了するものである。


System.setProperty("http.maxConnections", String.valueOf(CONST.CONNECTION_LIMIT));
System.setProperty("sun.net.http.errorstream.enableBuffering", "true");

...

int responseCode = -1;
HttpURLConnection conn = null;
BufferedReader reader = null;
try {
 conn = (HttpURLConnection) (new URL(url)).openConnection();
 conn.setRequestProperty("Accept-Encoding", "gzip");

 // this blocks until the connection responds
 InputStream in = new GZIPInputStream(conn.getInputStream());

 reader = new BufferedReader(new InputStreamReader(in));
 StringBuffer sb = new StringBuffer();
 char[] buff = new char[CONST.HTTP_BUFFER_SIZE];
 int cnt;

 while((cnt = reader.read(buff)) > 0) sb.append(buff, 0, cnt);

 reader.close();

 responseCode = conn.getResponseCode();
 if(responseCode != HttpURLConnection.HTTP_OK) throw new IOException("abnormal HTTP response code:"+responseCode);

 return sb.toString();

} catch(IOException e) {
    // consume error stream, otherwise, connection won't be reused
    if(conn != null) {
     try {
         InputStream in = ((HttpURLConnection)conn).getErrorStream();
         in.close();
         if(reader != null) reader.close();
     } catch(IOException ex) {
         log.fine(ex);
     }
    }

    // log exception    
    String rc = (responseCode == -1) ? "unknown" : ""+responseCode;
    log.severe("Error for HttpUtil.httpGet("+url+")\nServer returned an HTTP response code of '"+rc+"'");
    log.severe(e);
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top