什么是java.io.EOFException,消息:无法从服务器读取响应。预期读取 4 个字节,读取 0 个字节

2022-08-31 21:04:23

这个问题在SO中被问过几次,在其他网站上被问过很多次。但我没有得到任何满意的答案。

我的问题:
我有一个java Web应用程序,它使用简单的JDBC通过Glassfish应用程序服务器连接到mysql数据库。

我在具有以下配置的 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,两个重要的mysql服务器配置是:
wait_timeout:1800秒
connect_timeout:10秒
注意:部署在同一服务器中的其他应用程序连接到同一数据库并使用不同的池,运行平稳。

编辑-2 :在阅读了很多东西并期待一些积极的结果之后,我对我的连接池进行了这些更改。

最长等待时间 : 0 (以前是 60 秒)
连接验证 : 必需
的验证方法 :
表 名称 : 演示
验证 Atmost 一次 : 40 秒
创建 重试次数 : 1
重试间隔 : 5 秒
最大连接使用量 : 5

这有效,因为应用程序持续运行3天。但是我得到了一个非常奇怪和有趣的结果。在监视连接池时,我发现了以下数字:

NumConnAcquired : 44919 Count
NumConnRelease : 44919 Count
NumConnCreated : 9748 Count
NumConnDestroyed : 9793 Count
NumConnFailedValidation : 70 Count
NumConnFree : 161 Count
NumConUsed : -136 Count

怎么能变成161就像我一样
怎么会变成-136,一个
如何>NumConnFreeMaximum Pool Size = 100NumConnUsedNumConnDestroyedNumConnCreated


答案 1

连接失败,可能是由于防火墙空闲超时等原因。如果您没有将 JDBC 驱动程序配置为在失败时重新连接,则除非您打开新连接,否则此错误不会消失。

如果您使用的是数据库连接池(您正在使用一个,对吧?),那么您可能希望启用它的连接检查功能,例如发出查询以检查连接是否正常工作,然后再将其交还给应用程序。在 Apache commons-dbcp 中,这称为 the,通常设置为简单的东西,如 .validationQuerySELECT 1

由于您使用的是MySQL,因此您应该使用特定于连接器/ J的“ping”查询,该查询比实际发出真正的SQL查询更轻量级,并将验证查询设置为(ping部分需要精确)。/* ping */ SELECT 1


答案 2

这是 Java 中的 EndOfFileException,当游标起点位于端点上或由于某些意外异常而关闭数据库连接时,就会发生这种情况。


推荐