java.io.EOFExceptionとは何ですか、メッセージ:サーバからの応答を読み取ることができません。 4バイト読み込み、0バイト読み込み

この質問は、SOでは2回、他のサイトでは何度も聞かれてきました。しかし、私は満足のいく答えを得られませんでした。

私の問題:
私はGlassfishアプリケーションサーバーを通してmysqlデータベースに接続するために簡単なJDBCを使用するJava Webアプリケーションを持っています。

私は以下の設定でglassfishサーバーの接続プールを使用しました。
初期プールサイズ:25
最大プールサイズ:100
プールサイズ変更数量:2
アイドルタイムアウト:300秒
最大待機時間:60,000ミリ秒

このアプリケーションは過去3か月間にデプロイされており、完璧に動作していました。
しかし、過去2日間から、ログイン時に次のエラーが発生しています。

部分スタックトレース

com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: No operations allowed after connection closed.Connection was implicitly closed due to underlying exception/error:  

** BEGIN NESTED EXCEPTION **  

com.mysql.jdbc.CommunicationsException  
MESSAGE: Communications link failure due to underlying exception:  

** BEGIN NESTED EXCEPTION **  

java.io.EOFException  
MESSAGE: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.  

STACKTRACE:  

java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.  
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1997)  
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2411)  
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2916)  
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)  
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)  
at com.mysql.jdbc.Connection.execSQL(Connection.java:3256)  
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1313)  
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1448)  
............  
............  
my application traces....  

突然このエラーの原因は何ですか?私はこれのために多くの時間を失いました。

編集:問題は、サーバーを再起動した後も解決しません。 DBAによると、2つの重要なmysqlサーバー設定は以下のとおりです。
wait_timeout:1800秒
connect_timeout:10秒
注:同じデータベースに接続し、異なるプールを使用している同じサーバーに配置された他のアプリケーションは、スムーズに実行されています。

編集2:たくさんのことを読んで、いくつかの良い結果を期待した後、私は自分のコネクションプールにこれらの変更を加えました。

最大待機時間:0(以前は60秒でした)
接続検証:必須
検証方法:テーブル
テーブル名:デモ
最大1回検証:40秒
作成再試行回数:1
再試行間隔:5秒
最大接続使用量:5

アプリケーションが3日間一貫して実行されているので、これはうまくいきました。しかし、私はこれについて非常に奇妙で面白い結果を得ました。接続プールを監視していると、これらの数字が見つかりました。

NumConnAcquired:44919カウント
NumConnReleased:44919カウント
NumConnCreated:9748カウント
NumConnDestroyed:9793カウント
NumConnFailedValidation:70カウント
NumConnFree:161カウント
NumConnUsed:-136カウント

最大プールサイズ= 100の場合、NumConnFreeはどのように161になるのですか?
NumConnUsedはどうやって負の数の-136になるのですか?
NumConnDestroyed> NumConnCreated?

ベストアンサー
おそらくファイアウォールのアイドルタイムアウトなどが原因で接続が失敗しました。失敗したときにJDBCドライバが再接続するように設定されていない場合は、新しい接続を開かない限りこのエラーは消えません。

データベース接続プールを使用している場合(使用しているのではないでしょうか)、おそらく、接続を確認してアプリケーションに渡す前に接続が機能しているかどうかを確認するなどの接続確認機能を有効にします。 Apache commons-dbcpでは、これはvalidationQueryと呼ばれ、多くの場合SELECT 1のような単純なものに設定されています。

MySQLを使用しているので、実際に真のSQLクエリを発行するよりも軽量のConnector / J固有の “ping”クエリを使用し、検証クエリを/ * ping * / SELECT 1(pingパートneeds to be exact)に設定する必要があります。 )

転載記事の出典を記入してください: java.io.EOFExceptionとは何ですか、メッセージ:サーバからの応答を読み取ることができません。 4バイト読み込み、0バイト読み込み - コードログ