web-dev-qa-db-ja.com

URLがアップしているときに「Java.net.ConnectException:接続がタイムアウトしました」という例外が発生するのはなぜですか?

私のコードから何らかの頻度でConnectException: Connection timed outを取得しています。ヒットしようとしているURLはアップしています。同じコードは一部のユーザーには機能しますが、他のユーザーには機能しません。 1人のユーザーがこの例外の取得を開始すると、引き続き例外を取得するようです。

スタックトレースは次のとおりです。

Java.net.ConnectException: Connection timed out
Caused by: Java.net.ConnectException: Connection timed out
    at Java.net.PlainSocketImpl.socketConnect(Native Method)
    at Java.net.PlainSocketImpl.doConnect(PlainSocketImpl.Java:333)
    at Java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.Java:195)
    at Java.net.PlainSocketImpl.connect(PlainSocketImpl.Java:182)
    at Java.net.Socket.connect(Socket.Java:516)
    at Java.net.Socket.connect(Socket.Java:466)
    at Sun.net.NetworkClient.doConnect(NetworkClient.Java:157)
    at Sun.net.www.http.HttpClient.openServer(HttpClient.Java:365)
    at Sun.net.www.http.HttpClient.openServer(HttpClient.Java:477)
    at Sun.net.www.http.HttpClient.<init>(HttpClient.Java:214)
    at Sun.net.www.http.HttpClient.New(HttpClient.Java:287)
    at Sun.net.www.http.HttpClient.New(HttpClient.Java:299)
    at Sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.Java:796)
    at Sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.Java:748)
    at Sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.Java:673)
    at Sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.Java:840)

これが私のコードからの抜粋です:

URLConnection urlConnection = null;
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter = null;
InputStream inputStream = null;

try {
    URL url = new URL(urlBase);
    urlConnection = url.openConnection();
    urlConnection.setDoOutput(true);

    outputStream = urlConnection.getOutputStream(); // exception occurs on this line
    outputStreamWriter = new OutputStreamWriter(outputStream);
    outputStreamWriter.write(urlString);
    outputStreamWriter.flush();
    inputStream = urlConnection.getInputStream();
    String response = IOUtils.toString(inputStream);
    return processResponse(urlString, urlBase, response);
} catch (IOException e) {
    throw new Exception("Error querying url: " + urlString, e);
} finally {
    IoUtil.close(inputStream);
    IoUtil.close(outputStreamWriter);
    IoUtil.close(outputStream);
}
79
Sarah Haskins

接続タイムアウト(ローカルネットワークと複数のクライアントマシンを想定)は通常、

a)送信者に「ホストへのルートなし」などのことを通知せずに、単にパケットを食べる方法のある種のファイアウォール

b)ネットワーク設定の誤りまたは回線の過負荷によるパケット損失

c)サーバーに負荷がかかりすぎるリクエスト

d)サーバー上で同時に使用可能な少数のスレッド/プロセスは、それらすべてを取得します。これは、実行に時間がかかり、c)と組み合わされる可能性がある要求で特に発生します。

お役に立てれば。

78
Jumpy

同じマシンのWebブラウザーでURLが正常に機能する場合、ブラウザーがURLへの接続に使用しているHTTPプロキシをJavaコードが使用していない可能性があります。

29
Alexander

エラーメッセージにすべてが記載されています:接続がタイムアウトしました。これは、ある(デフォルトの)時間枠内にリクエストが応答を受け取らなかったことを意味します。応答が受信されなかった理由は、次のいずれかです。

a)IP /ドメインまたはポートが正しくありません

b)IP /ドメインまたはポート(つまりサービス)がダウンしている

c)IP /ドメインが応答するためにデフォルトのタイムアウトよりも長くかかっている

d)使用しているポートで要求または応答をブロックしているファイアウォールがある

e)その特定のホストへのリクエストをブロックしているファイアウォールがある

f)インターネットアクセスがダウンしています

g)ライブサーバーがダウンしています。つまり、「残りのAPI呼び出し」の場合です。

ISPによってファイアウォールとポートまたはIPブロッキングが設定されている場合があることに注意してください

5
M Hamza Javed

次のように、出力ストリームを取得する前に接続タイムアウト時間を増やすことをお勧めします。

urlConnection.setConnectTimeout(1000);

1000はミリ秒単位です(1000ミリ秒= 1秒)。

4
Powerlord
  • telnetを実行してファイアウォールの問題を確認してください
  • tracert/tracerouteを実行して、ホップ数を見つけます
3

私は私の問題を解決しました:

System.setProperty("https.proxyHost", "myProxy");
System.setProperty("https.proxyPort", "80");

またはhttp.proxyHost...

2
NikNik

これはIPv6の問題である可能性があります(ホストはIPv6 AAAAアドレスを公開し、ユーザーホストはIPv6用に構成されていると考えていますが、実際には正しく接続されていません)。これは、ネットワークMTUの問題、ファイアウォールのブロック、またはターゲットホストがすべて到達可能ではない(ランダムに、または発信者の国に基づいて)異なるIPアドレスを公開する可能性もあります。または同様のネットワークの問題。

タイムアウトを設定し、適切なエラーメッセージを追加する(特にホストの解決済みアドレスを出力する)以外には、多くのことはできません。より堅牢にしたい場合は、再試行を追加し、すべてのアドレスを並行して試行し、Javaプラットフォームでの名前解決キャッシング(ポジティブおよびネガティブ)も調べます。

1
eckes

IP /ホストがリモートホストによってブロックされている可能性があります。特に、あまりにも激しくヒットしていると思われる場合。

0
larsivi

これが私に起こった理由は、リモートサーバーが特定のIPアドレスのみを許可し、それ自体を許可していなかったため、サーバーのURLから画像をレンダリングしようとしていたためです...持っていました...

サーバーが自身のIPを許可していること、または実際に存在するリモートURLからのものをレンダリングしていることを確認してください。

0
Damir Olejar