什么是java.io.EOFException,消息:无法从服务器读取响应。预计读取4个字节,读取0个字节 [英] what is java.io.EOFException, Message: Can not read response from server. Expected to read 4 bytes, read 0 bytes

查看:14635
本文介绍了什么是java.io.EOFException,消息:无法从服务器读取响应。预计读取4个字节,读取0个字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我的问题:

我有一个使用简单 JDBC 连接到 mysql 数据库通过 Glassfish 应用程序服务器。



我在glassfish服务器中使用了以下配置的连接池:

初始池大小:25

最大池大小:100

池调整大小数量:2

空闲超时:300秒

最长等待时间:60,000毫秒



应用程序已部署了最近3个月,它运行正常。

但是从最近2天以下错误在登录时出现。



部分StackTrace

  com。 mysql.jdbc.exceptions.MySQLNonTransientConnectionException:在连接之后不允许操作closed.Connection由于基础异常/错误而隐式关闭:

** BEGIN NESTED EXCEPTION **

com .mysql.jdbc.CommunicationsException
MESSAGE:由于基础异常导致的通信链接失败:

** BEGIN NESTED EXCEPTION **

java.io.EOFException
MESSAGE:无法从服务器读取响应。预期读取4个字节,在连接意外丢失之前读取0个字节。

STACKTRACE:

java.io.EOFException:无法从服务器读取响应。预期读取4个字节,在连接意外丢失之前读取0个字节。
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)
............
............
我的应用程序跟踪....

/ strong>我已失去了很多时间。



编辑:重新启动服务器后问题仍然存在。根据DBA,两个重要的mysql服务器配置是:

wait_timeout: 1800秒

connect_timeout: 10秒

注意:连接到同一个数据库并使用不同池的同一台服务器中部署的其他应用程序运行顺畅。



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



最长等待时间: 0(先前为60秒)

连接验证:必需

验证方法:

表名称:演示

验证Atmost一次: 40秒

创建重试尝试: 1

重试间隔: 5秒

最大连接使用量: 5



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



NumConnAcquired: 44919计数

NumConnReleased: / strong> 44919计数

NumConnCreated: 9748计数

NumConnDestroyed: 9793计数

NumConnFailedValidation: 70计数

NumConnFree: 161计数

NumConnUsed:

如何可以 NumConnFree 成为161,因为我有最大池大小= 100 c>

如何可将 NumConnUsed > NumConnCreated

解决方案

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



如果您使用数据库连接池(使用一个,对吧?),那么您可能需要启用它的连接检查功能,例如发出查询以检查连接是否工作,然后将其返回到应用程序。在Apache commons-dbcp中,这被称为 validationQuery ,通常设置为像 SELECT 1 p>

由于你使用MySQL,你应该使用一个连接器/ J特定的ping查询比实际发出真正的SQL查询更轻,并设置验证查询到 / * ping * / SELECT 1 (ping部分需要准确)。


This question has been asked a couple of times in SO and many times in other sites. But I didn't get any satisfiable answer.

My problem:
I have a java web application which uses simple JDBC to connect to mysql database through Glassfish application server.

I have used connection pooling in glassfish server with the following configurations:
Initial Pool Size: 25
Maximum Pool Size: 100
Pool Resize Quantity: 2
Idle Timeout: 300 seconds
Max Wait Time: 60,000 milliseconds

The application has been deployed for last 3 months and it was running flawlessly too.
But from last 2 days the following error is coming at the time of login.

Partial StackTrace

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....  

What caused this error suddenly ? I have lost a lot of time for this.

EDIT : The problem even persists after restarting the server. As per DBA two of the important mysql server configurations are:
wait_timeout : 1800 seconds
connect_timeout : 10 seconds
NOTE : Other applications deployed in the same server connecting to the same database and using different pools are running smoothly.

EDIT-2 : After reading a lot of things and expecting some positive outcome I made these changes to my connection pool.

Max Wait Time : 0 (previously it was 60 seconds)
Connection Validation : Required
Validation Method : table
Table Name : Demo
Validate Atmost Once : 40 seconds
Creation Retry Attempts : 1
Retry Intervals : 5 seconds
Max Connection Usage : 5

And this worked as the application is running for 3 days consistently. But I got a very strange and interesting result of out this. While monitoring the connection pool, I found these figures:

NumConnAcquired : 44919 Count
NumConnReleased : 44919 Count
NumConnCreated : 9748 Count
NumConnDestroyed : 9793 Count
NumConnFailedValidation : 70 Count
NumConnFree : 161 Count
NumConnUsed : -136 Count

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 ?

解决方案

The connection has failed, possibly due to a firewall idle-timeout, etc. If you don't have your JDBC driver configured to reconnect on failure, then this error will not go away unless you open a new connection.

If you are using a database connection pool (you are using one, right?), then you probably want to enable it's connection-checking features like issuing a query to check to see if the connection is working before handing it back to the application. In Apache commons-dbcp, this is called the validationQuery and is often set to something simple like SELECT 1.

Since you are using MySQL, you ought to use a Connector/J-specific "ping" query that is lighter-weight than actually issuing a true SQL query and set your validation query to /* ping */ SELECT 1 (the ping part needs to be exact).

这篇关于什么是java.io.EOFException,消息:无法从服务器读取响应。预计读取4个字节,读取0个字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆