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

什么是java.io.EOFException,消息:无法从服务器读取响应。预期读取4个字节,读取0个字节,java,mysql,glassfish,connection,pool,Java,Mysql,Glassfish,Connection,Pool,这个问题在SO中被问了好几次,在其他网站上也被问了很多次。但我没有得到任何令人满意的答案 我的问题: 我有一个java web应用程序,它使用simpleJDBC通过Glassfish应用服务器连接到mysql数据库 我在glassfish服务器中使用了以下配置的连接池: 初始池大小:25 最大池大小:100 池大小调整数量:2 空闲超时:300秒 最大等待时间:60000毫秒 该应用程序已经部署了3个月,而且运行也完美无缺。 但从最近2天开始,在登录时出现以下错误 部分堆栈跟踪 com.mys

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

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

我在glassfish服务器中使用了以下配置的连接池:
初始池大小:25
最大池大小:100
池大小调整数量:2
空闲超时:300秒
最大等待时间:60000毫秒

该应用程序已经部署了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服务器的两个重要配置是:
等待\u超时:1800秒
连接\u超时:10秒
注意:部署在同一服务器上、连接到同一数据库并使用不同池的其他应用程序正在顺利运行

EDIT-2:在阅读了大量内容并期待一些积极的结果后,我对我的连接池进行了这些更改

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

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

numconn要求:44919计数
NumConnReleased:44919计数
NumConnCreated:9748计数
numconndestried:9793计数
NumConnFailedValidation:70计数
NumConnFree:161计数
numconused:-136计数

当我拥有
最大池大小=100时,
NumConnFree
如何成为161?

使用的
数值
如何变成-136,一个负数

NumConnDestroyed
NumConnDestroyed
NumConnCreated
?这很可能意味着数据库已重新启动或与数据库的网络连接已中断(例如,NAT连接已超时)。。。您的webapp正在尝试使用过时的数据库连接

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....  
如果重新启动web容器后问题仍然存在,则可能是更严重的问题


你问了以下问题:

How can the NumConnFree become 161 as I have Maximum Pool Size = 100 ?
How can the NumConnUsed become -136, a negative number ?
How can the NumConnDestroyed > NumConnCreated ? 

表面上看,这些都没有道理。但是,它们可能只是以非线程安全的方式更新某些使用计数器的结果。这不一定与您的原始问题有关。

这是java中的EndOfFileException,发生在光标起点位于终点或由于某些意外异常而关闭数据库连接时。

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

如果您使用的是数据库连接池(您使用的是数据库连接池,对吗?),那么您可能希望启用它的连接检查功能,例如在将连接交还给应用程序之前发出查询以检查连接是否正常工作。在Apache commons dbcp中,这称为
validationQuery
,通常设置为类似
SELECT 1
的简单值


因为您使用的是MySQL,所以应该使用连接器/J特定的“ping”查询,它比实际发出真正的SQL查询更轻,并将验证查询设置为
/*ping*/SELECT 1
(ping部分)。

虽然我没有确定的解决方案,似乎有什么东西干扰了应用服务器和数据库之间的通信。以下是您可以尝试隔离问题的几件事:

  • 尝试确定这是mysql问题还是java代码问题。尝试使用命令行工具从与应用服务器相同的主机连接到mysql,并发出类似的SQL来执行登录。使用一个简单的java代码进行测试,进行选择,将其部署到相同的基础设施,查看发生了什么等。同时检查mysql服务器日志,看看是否可以找到有用的内容

  • 有两种方法可以关闭空闲连接:通过在AppServer内部运行的连接池代码,或者通过mysql本身。确保检查两侧的配置

  • 检查最近是否更改了任何网络基础结构配置。是否有任何新的防火墙规则干扰app server mysql连接?是否有任何设置禁止开放TCP连接空闲时间超过X

  • 尝试不同的连接池库,以消除连接池的可能性


祝你好运

这可能是防火墙相关的问题。

我有这个问题,但我无法更改MySQL数据库配置。因此,我确保在我的sql连接器类中,连接在再次启动之前总是关闭的。比如:

public static Connection getConnection() {

    if (DatabaseConnnector.conn == null) {
        initConn();
    } else {
        try {
            DatabaseConnnector.conn.close();          
        } catch (SQLException e) {
            e.printStackTrace();
        }
          initConn();
    }
    return DatabaseConnnector.conn;
}

这就解决了问题

在PHPStorm whil中获得此错误