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

2019-07-05 21:20发布

这个问题已经被问了几次,在其他网站,所以和很多次。 但我没有得到任何令人满意的答案。

我的问题:
我有一个使用简单的JDBC通过GlassFish应用服务器连接到MySQL数据库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两个重要的MySQL服务器的配置是:
WAIT_TIMEOUT:1800
connect_timeout:10
注:部署在同一台服务器的其他应用程序连接到同一个数据库,并使用不同的池平稳运行。

EDIT 2:读了很多东西,并期望我做了这些改变我的连接池中的某些积极成果之后。

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

而这个工作作为应用程序运行3天持续。 但我得到的这份非常奇怪和有趣的结果。 当监控连接池,我发现这些数字:

NumConnAcquired:44919计数
NumConnReleased:44919计数
NumConnCreated:9748计数
NumConnDestroyed:9793计数
NumConnFailedValidation:70伯爵
NumConnFree:161计数
NumConnUsed:-136计数

如何才能NumConnFree成为161,因为我有Maximum Pool Size = 100
如何才能NumConnUsed变成-136, 负数
如何才能NumConnDestroyed > NumConnCreated

Answer 1:

连接失败,可能是由于防火墙空闲超时时间等,如果你没有配置重新连接上失败的JDBC驱动程序,那么这个错误不会,除非你打开一个新的连接消失。

如果您使用的是数据库连接池( 使用一个吧?),那么你可能要启用它就像发出一个查询来检查,看看是否连接递回给应用程序之前工作的连接检查功能。 在Apache中的commons-DBCP,这就是所谓的validationQuery ,常常设置为一些简单的像SELECT 1

既然你使用MySQL,你应该使用一个连接器/ J-特定的“ping”查询更轻重量比实际发出真正的SQL查询,您的验证查询设置为/* ping */ SELECT 1 (平部分需求要准确 )。



Answer 2:

这很可能意味着该数据库已重新启动或网络连接到数据库已被打破(如NAT连接超时)...和你的web应用程序正在试图使用过时的数据库连接。

如果重新启动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 ? 

在它面前,这没有任何意义。 然而,他们可能仅仅是在非线程安全的方式进行更新一些使用计数器的结果。 这不一定与你原来的问题。



Answer 3:

这是EndOfFileException在Java中,发生在你的光标起始点上的端点或当数据库连接被关闭,因为一些意外的异常。



Answer 4:

虽然我没有明确的解决方案,似乎事情是干扰应用服务器和数据库之间的通信。 以下是几件事情,你可以尝试找出问题:

  • 尝试确定阉这是MySQL的问题或Java代码的问题。 尝试连接使用同一主机作为应用服务器的命令行工具,MySQL和发出类似SQL进行登录。 用一个简单的Java代码,做了选择测试,它部署到同一个基础设施,看看有什么发生等还检查了MySQL服务器日志,看看你是否能找到什么有用的东西

  • 有两种方式之间的空闲连接关闭后得到:通过应用程序服务器内运行的连接池的代码,或由MySQL本身。 请务必检查两侧配置

  • 检查是否有任何网络基础设施的配置最近发生了变化。 有没有到位与应用服务器干扰任何新的防火墙规则< - > mysql的连接? 在那里,禁止打开的TCP连接空转比X不再有任何设置?

  • 尝试不同的连接池库只是为了消除可能它的连接池

祝好运



Answer 5:

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



Answer 6:

我有这个问题,但我不可能对我来说,使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;
}

这解决了这个问题。



文章来源: what is java.io.EOFException, Message: Can not read response from server. Expected to read 4 bytes, read 0 bytes