如何解决这个java mysql异常:通信链接失败?

时间:2018-01-15 11:54:49

标签: mysql jdbc

以下是此例外的日志:

    com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 1,409,240 milliseconds ago.  The last packet sent successfully to the server was 1,409,267 milliseconds ago.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:989)
        at com.mysql.jdbc.MysqlIO.nextRowFast(MysqlIO.java:2229)
        at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1989)
        at com.mysql.jdbc.MysqlIO.readSingleRowSet(MysqlIO.java:3410)
        at com.mysql.jdbc.MysqlIO.getResultSet(MysqlIO.java:470)
        at com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(MysqlIO.java:3112)
        at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:2341)
        ...
Caused by: java.io.EOFException: Can not read response from server. Expected to read 7 bytes, read 5 bytes before connection was unexpectedly lost.
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3011)
        at com.mysql.jdbc.MysqlIO.nextRowFast(MysqlIO.java:2212)

我知道这个例外非常正常,我已经用Google搜索并获得了很多解决方案。但是,这些解决方案都没有解决我的问题。嗯,它只是一个简单的java应用程序,而不是java Web应用程序,我没有使用任何连接池,只是简单地使用了JDBC。我的mysql版本是5.7.12。并且mysql在Windows服务器上运行,而java应用程序在linux上运行。我检查了“等待时间”'对于mysql和它的28800,远远大于1409240毫秒。所以问题可能不应该是由这个问题造成的。我还检查了我的linux上的tcp连接等待时间,它是7200s,仍远大于1409240 ms。我也试过添加'?autoReconnect = true'到JDBC网址,但它仍然没有区别。而且我确信我的服务器的可访问性没有任何问题,因为在问题发生之前连接确实可以运行几分钟。我几乎尝试过任何我能做的事情。但是,问题仍然存在。我该怎么办?是否存在问题是由Windows防火墙引起的可能性?

编辑: 执行SELECT查询尝试从大小为10.9 G的表中选择所有数据项时会发生此问题。也许此表太大,以至于句子 ResultSet rs = stmt.executeQuery(sql); 无法完成。但是我已经检查了“max_execution_time”' mysql的变量,它被设置为0,表示没有执行时间的限制。

2 个答案:

答案 0 :(得分:2)

欢迎使用TCP / IP。很多事情都可能导致TCP连接丢失,特别是那些闲置一段时间的连接。正如你所提到的,其中一个就是防火墙。即使客户端和服务器都同意它应该保持活动,某些网络实体也可以连接该连接。当客户端和服务器不在同一本地网络上时,连接丢失可能性会增加。

找出为什么意味着在网络中的不同位置进行大量的数据包监控。这可能耗费大量的时间和精力而不会教你太多。另外,学习阅读wireshark输出是一项真正的任务。

大多数需要持久连接的客户端 - 服务器程序员都使用某种keepalive操作来避免连接闲置太久。 Keepalive操作会发送一些内容并获得回报。在您的情况下,您可以通过每隔一两分钟发出一次SELECT NOW()查询(或其他一些往返无操作)来轻松完成此操作,而客户端则处于空闲状态。

处理此类事情的最佳方法是在需要时打开数据库连接,然后在完成后关闭它。如果使用连接池功能,则可以在每次查询时打开和关闭池化连接,并且仍然可以避免搅动物理连接。 JDBC连接器和MySQL服务器代码针对此方法进行了优化;这可能是最好的方式。

答案 1 :(得分:0)

我让com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure阅读了更多错误消息,我意识到这与连接字符串中的SSL设置有关。 当您在MySQL的连接字符串中启用了SSL后,请确保您的日期和时间正确或与当前日期同步。否则,连接将被javax.net.ssl.SSLHandshakeException击中,从而导致last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. 。提示您对约会进行一些操作。这就是我解决我问题的方法。我必须正确设置日期和时间。有时错误消息说明了很多问题。