web-dev-qa-db-ja.com

java.net.SocketTimeoutException:読み取りがタイムアウトしました

クライアントサーバーアーキテクチャを備えたアプリケーションがあります。クライアントはJava Web Start with Java Swing/AWTを使用し、sertはTomcatでHTTPサーバー/サーブレットを使用します。通信はオブジェクトのシリアル化から行われます。 ObjectOutputを作成すると、バイト配列がシリアル化され、それぞれObjectInputStreamと呼ばれるサーバーに送信されて逆シリアル化されます。

アプリケーションは、エラー「SocketException読み取りタイムアウト」を表示し始める特定の同時実行時間に正しく通信します。サーバーがサーブレットのdoPostメソッドでメソッドObjectInputStream.getObject()を呼び出すと、エラーが発生します。

Tomcatの速度が低下し、サーバーの再起動が必要なクラッシュ時まで、すべてが機能した後、エラーによってサーバーの応答時間が短縮され始めます。

誰かがこの問題を経験しましたか?

クライアントコード

URLConnection conn =  url.openConnection();
conn.setDoOutput(true);

OutputStream os = conn.getOutputStream();
ObjectOutputStream oss = new ObjectOutputStream(os);

oss.writeUTF("protocol header sample");

oss.writeObject(_parameters);
oss.flush();
oss.close();

サーバーコード

ObjectInputStream input = new ObjectInputStream(_request.getInputStream());
String method = input.readUTF();

parameters = input.readObject();

input.readObject()は、エラーが発生する場所です

8
Rafael Soto

特にクライアント側については、先に進むための多くの情報を提供してくれませんでした。しかし、私の疑いは、クライアント側が次のとおりであるということです。

  • content-lengthヘッダーの設定に失敗した(または間違った値に設定した)、
  • 出力ストリームのフラッシュに失敗した、および/または
  • ソケットの出力側を閉じていません。

不思議。

更新された質問に基づくと、上記のいずれでもないようです。他のいくつかの可能性があります:

  • 何らかの理由で、クライアント側はシリアル化中に完全にロックアップするか、非常に長い時間がかかります。
  • 問題を引き起こしているクライアントとサーバーの間にプロキシがあります。
  • 負荷関連のネットワークの問題、またはネットワークハードウェアの問題が発生しています。

もう1つの考えられる説明は、メモリリークがあり、メモリが不足するにつれてGCがますます時間がかかることが原因で速度が低下することです。有効にしている場合、これはGCログに表示されます。

10
Stephen C

同時実行性が高いと、Tomcatで設定されたソケットタイムアウトが期限切れになり、接続が閉じられると思います。その接続に対してTomcatが次に読み取るのは、サーバーで指定されたサーバーソケットタイムアウトよりも大きい。
この問題を回避したい場合は、サーバー側のタイムアウトを増やす必要があります。このタイムアウトは、ケースで期限切れになります。ただし、お勧めできません。
ところで、あなたは十分な情報を提供しませんでした。 Tomcatで接続するスレッドの数を増やしましたか?もしそうなら、これは確かに起こるでしょう。

0
vetri