1

Tomcat で Web アプリケーションを実行しています。私のアプリケーションは、クライアントからの要求を満たすために他の Web サービスに接続します。URL 接続を開いているときに java.net.UnknownHostException が発生することがあります。その後、java.net.SocketException: Too many open files が発生し始めます。そして、私のサーバーは接続の受け入れを停止します。ガイドしてください。

String  response;
    HttpURLConnection conn = null;
BufferedReader rd = null;
InputStream in = null;
try
{
    // Send data
    String urlStr = URL;
    URL url = new URL(urlStr);
    conn = (HttpURLConnection)url.openConnection();
    conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
    int contentLength = conn.getContentLength();
    //   System.out.println("content length 1" +  contentLength);
    if (contentLength <= 0)
    {
        InputStream in1 = (conn).getErrorStream();
        if (in1 != null)
        {
            in1.close();
        }
        conn.getInputStream().close();
        in = null;
        conn.disconnect();
        conn = null;
        return null;
    }
    in = conn.getInputStream();
    if (conn.getResponseCode() != 200)
    {
        InputStream in1 = (conn).getErrorStream();
        if (in1 != null)
        {
            in1.close();
        }
        conn.getInputStream().close();
        in = null;
        conn.disconnect();
        conn = null;
        in.close();
        in = null;
        return null;
    }
    // Get the response
    rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    StringBuffer stringBuffer = new StringBuffer();
    String line = null;
    while ((line = rd.readLine()) != null)
    {
        stringBuffer.append(line);
    }
    response = stringBuffer.toString();
    System.out.println("full ads response = " + response);
}
catch (Exception ex)
{
    //   ex.printStackTrace();
}
finally
{
    try
    {
        if (conn != null)
        {
            InputStream in1 = (conn).getErrorStream();
            if (in1 != null)
            {
                in1.close();
            }
            conn.getInputStream().close();
            in = null;
            conn.disconnect();
            conn = null;
        }
        if (rd != null)
        {
            rd.close();
            rd = null;
        }
        if (in != null)
        {
            in.close();
            in = null;
        }
    }
    catch (Exception e)
    {
    }
}
return null;        
4

4 に答える 4

2

UnknownHostException使用した URL が存在しないホスト名を参照しているか、ホスト名の DNS レコードまたはシステムがその瞬間に移行中であったことを意味します。

ソケット リークは、以下の過剰なクリーンアップ コードが原因である可能性があります。コメントを参照してください。

すべての例外を抑制すると、Hades で何が問題なのかを突き止められるという希望がなくなります。だから、それを修正する最初のことです。例外を無視しないでください。それらをログに記録します。それらのスタック トレースを出力します。何かをしてください。

ただし、コードには他にも多くの問題があります。

HttpURLConnection conn = null;
BufferedReader rd = null;
InputStream in = null;
try
{
    // Send data
    String urlStr = URL;

この変数は冗長です。以下を使用するだけURLです。

    URL url = new URL(urlStr);
    conn = (HttpURLConnection)url.openConnection();
    conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");

ここまではOK。

    int contentLength = conn.getContentLength();
    //   System.out.println("content length 1" +  contentLength);
    if (contentLength <= 0)

コンテンツの長さがゼロであることを確認することは非常にまれです。これはエラーをチェックするためのプロキシですか? 私は単にこのテストを削除します。

    {
        InputStream in1 = (conn).getErrorStream();
        if (in1 != null)
        {
            in1.close();
        }
        conn.getInputStream().close();
        in = null;
        conn.disconnect();
        conn = null;
        return null;
    }

上記はすべて冗長です。あなたはすでにfinallyブロックにそれを持っています。それを除く。

    in = conn.getInputStream();
    if (conn.getResponseCode() != 200)

以上がエラーのチェック方法です。ただし、呼び出すgetResponseCode() に呼び出す必要があります。そうしないと、応答コードが 404 であることに関心があるgetInputStream(),場合に、後者がスローされる可能性があります。FileNotFoundException

    {
        InputStream in1 = (conn).getErrorStream();
        if (in1 != null)
        {
            in1.close();
        }
        conn.getInputStream().close();
        in = null;
        conn.disconnect();
        conn = null;
        in.close();
        in = null;
        return null;
    }

繰り返しますが、上記はすべて冗長です。あなたはすでにfinallyブロックにそれを持っています。それを除く。

    // Get the response
    rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    StringBuffer stringBuffer = new StringBuffer();
    String line = null;

の初期化lineは冗長です。変数は次の行で割り当てられます。それを除く。

    while ((line = rd.readLine()) != null)
    {
        stringBuffer.append(line);
    }
    response = stringBuffer.toString();
    System.out.println("full ads response = " + response);
}
catch (Exception ex)

ここでしか釣れませんIOException

{
    //   ex.printStackTrace();

例外を無視しないでください。

}
finally
{
    try
    {
        if (conn != null)
        {
            InputStream in1 = (conn).getErrorStream();
            if (in1 != null)
            {
                in1.close();
            }

エラー ストリームを取得または閉じる必要はありません。これをすべて削除します。

            conn.getInputStream().close();
            in = null;

この変数を null に設定しても意味がありません。これはローカル変数なので、いずれにせよ範囲外になります。

            conn.disconnect();
            conn = null;

同上。

        }
        if (rd != null)
        {
            rd.close();
            rd = null;
        }

入力ストリームは既に閉じています。これは冗長です。このブロックを削除します。

        if (in != null)
        {
            in.close();
            in = null;
        }

接続の入力ストリームは既に閉じています。これはすべて冗長です。それを除く。

    }
    catch (Exception e)
    {
    }

繰り返しますが、ここでキャッチするだけでIOException、エラーを無視してはいけません。個人的には、メソッド throw がIOExceptionあり、catch ブロックはまったくありません。null を返すことは、呼び出し元にとってあまり役に立ちません。一般的には、何がうまくいかなかったのかを正確に知っている方がよいので、それに対して何をすべきかについて有用な決定を下すことができます。

}
return null;        
于 2013-04-10T05:43:40.827 に答える
0

修正するには、Linux サーバーの開いているファイルの制限を増やしてみてくださいjava.net.SocketException: Too many open files。最大ファイル数の制限は、Linux のこのファイルに保存されます。

/proc/sys/fs/file-max

現在開いているファイルを確認するには、次を使用できます。

lsof

番号を確認します。開いているファイルの場合、次を使用します。

lsof | wc -l

また、conn.disconnect() に加えて、接続を閉じます conn.close()。inputreader も必ず閉じてください。そのようなクローズはすべてfinallyブロックで行う必要があるため、例外が発生した場合にも接続がクローズされます。

于 2013-04-10T05:10:42.517 に答える
0

Windows または Linux で実行していますか? この記事をチェックして、お役に立てば幸いです: http://edmund.haselwanter.com/en/blog/2009/03/13/tomcat-too-many-open-files/

于 2013-04-10T05:10:58.580 に答える