使用 JDBC 和 MySQL 解决“通信链路故障”[重复]

Posted

技术标签:

【中文标题】使用 JDBC 和 MySQL 解决“通信链路故障”[重复]【英文标题】:Solving a "communications link failure" with JDBC and MySQL [duplicate] 【发布时间】:2011-07-28 20:55:24 【问题描述】:

我正在尝试连接到本地 mysql 服务器,但我不断收到错误消息。

这里是代码。

public class Connect 

    public static void main(String[] args) 
        Connection conn = null;

        try 
            String userName = "myUsername";
            String password = "myPassword";

            String url = "jdbc:mysql://localhost:3306/myDatabaseName";
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            conn = DriverManager.getConnection(url, userName, password);
            System.out.println("Database connection established");
         catch (Exception e) 
            System.err.println("Cannot connect to database server");
            System.err.println(e.getMessage());
            e.printStackTrace();
         finally 
            if (conn != null) 
                try 
                    conn.close();
                    System.out.println("Database Connection Terminated");
                 catch (Exception e) 
            
        
    

和错误:

Cannot connect to database server
Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:344)
        at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2333)
        at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2370)
        at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2154)
        at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:792)
        at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
        at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:381)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305)
        at java.sql.DriverManager.getConnection(DriverManager.java:582)
        at java.sql.DriverManager.getConnection(DriverManager.java:185)
        at Connect.main(Connect.java:16)
    Caused by: java.net.ConnectException: Connection refused
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
        at java.net.Socket.connect(Socket.java:529)
        at java.net.Socket.connect(Socket.java:478)
        at java.net.Socket.<init>(Socket.java:375)
        at java.net.Socket.<init>(Socket.java:218)
        at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:257)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:294)
        ... 15 more

我已设置类路径,确保 my.cnf 已将跳过网络选项注释掉。

java 版本为 1.2.0_26(64 位) mysql 5.5.14 mysql 连接器 5.1.17

我确保用户可以访问我的数据库。

【问题讨论】:

请注意底部的 CausedBy。 SQL 服务器从不接受连接。如果(从命令行)telnet localhost 3306 会发生什么? mySQL 服务器是否正在运行? 查看这篇文章。可能有帮助:***.com/questions/15949/… 问题已解决,在 my.cnf 中添加了绑定地址条目。 @Anthony 您应该将您的评论作为答案并接受它... 我尝试在控制面板中进入 Windows 服务并启动 mysql 服务,然后它工作了..试试这个解决方案 【参考方案1】:

我在我的两个程序中遇到了同样的问题。我的错误是:

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

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.

我花了几天时间来解决这个问题。我已经测试了许多在不同网站中提到的方法,但没有一个有效。最后,我更改了代码并发现了问题所在。我会尝试告诉您不同的方法并在这里总结一下

当我在互联网上寻找解决此错误的方法时,我发现有许多解决方案至少对一个人有效,但其他人却说对他们不起作用! strong> 为什么有很多方法可以解决这个错误? 似乎此错误一般在连接到服务器出现问题时会发生。问题可能是因为查询字符串错误或与数据库的连接过多。

所以我建议你一个一个尝试所有的解决方案,不要放弃!

这是我在互联网上找到的解决方案,对于每个解决方案,至少有一个人的问题已通过该解决方案得到解决。

提示:关于您需要更改 MySQL 设置的解决方案,您可以参考以下文件:

Linux:/etc/mysql/my.cnf/etc/my.cnf(取决于使用的 Linux 发行版和 MySQL 包)

Windows:C:\**ProgramData**\MySQL\MySQL Server 5.6\my.ini(注意它是 ProgramData,而不是 Program Files)

以下是解决方案:

更改bind-address 属性:

取消注释 bind-address 属性或将其更改为以下 IP 之一:

 bind-address="127.0.0.1"

 bind-address="0.0.0.0"

注释掉“跳过网络”

如果您的 MySQL 配置文件中有 skip-networking 行,请在该行的开头添加 # 符号以使其注释。

更改“wait_timeout”和“interactive_timeout”

将这些行添加到 MySQL 配置文件中:

[wait_timeout][1] = *number*

interactive_timeout = *number*

connect_timeout = *number*

确保 Java 没有将 'localhost' 转换为 [:::1] 而不是 [127.0.0.1]

由于 MySQL 识别 127.0.0.1 (IPv4) 但不识别 :::1 (IPv6)

这可以通过使用以下两种方法之一来避免:

    在连接字符串中使用127.0.0.1 而不是localhost 以避免localhost 被转换为:::1

    使用选项-Djava.net.preferIPv4Stack=true 运行java 以强制java 使用IPv4 而不是IPv6。在 Linux 上,这也可以通过运行(或将其放在 /etc/profile 中:

     export _JAVA_OPTIONS="-Djava.net.preferIPv4Stack=true"
    

检查操作系统代理设置、防火墙和防病毒程序

确保防火墙或防病毒软件没有阻止 MySQL 服务。

在 linux 上暂时停止 iptables。如果 iptables 配置错误,它们可能允许将 tcp 数据包发送到 mysql 端口,但会阻止 tcp 数据包从同一连接返回。

 # Redhat enterprise and CentOS
 systemctl stop iptables.service
 # Other linux distros
 service iptables stop

停止 Windows 上的防病毒软件。

更改连接字符串

检查您的查询字符串。你的连接字符串应该是这样的:

dbName = "my_database";
dbUserName = "root";
dbPassword = "";
String connectionString = "jdbc:mysql://localhost/" + dbName + "?user=" + dbUserName + "&password=" + dbPassword + "&useUnicode=true&characterEncoding=UTF-8";

确保字符串中没有空格。所有的连接字符串都应该继续,没有任何空格字符。

尝试将“localhost”替换为环回地址 127.0.0.1。 还可以尝试将端口号添加到您的连接字符串中,例如:

String connectionString = "jdbc:mysql://localhost:3306/my_database?user=root&password=Pass&useUnicode=true&characterEncoding=UTF-8";

MySQL 的默认端口通常是 3306。

不要忘记将用户名和密码更改为您的 MySQL 服务器的用户名和密码。

更新您的 JDK 驱动程序库文件 测试不同的 JDK 和 JRE(如 JDK 6 和 7) 不要更改 max_allowed_pa​​cket

“max_allowed_packet”是 MySQL 配置文件中的一个变量,表示最大数据包大小,而不是最大数据包数。所以解决这个错误无济于事。

更改 tomcat 安全性

将 TOMCAT6_SECURITY=yes 更改为 TOMCAT6_SECURITY=no

使用 validationQuery 属性

使用 validationQuery="select now()" 确保每个查询都有响应

自动重新连接

将此代码添加到您的连接字符串:

&autoReconnect=true&failOverReadOnly=false&maxReconnects=10

虽然这些解决方案都不适合我,但我建议您尝试一下。因为有些人按照这些步骤解决了他们的问题。

但是什么解决了我的问题?

我的问题是我在数据库上有很多 SELECT。每次我创建一个连接然后关闭它。虽然我每次都关闭连接,但系统面临许多连接并给我那个错误。 我所做的是将我的连接变量定义为整个类的公共(或私有)变量,并在构造函数中对其进行初始化。然后每次我只使用该连接。它解决了我的问题,也大大提高了我的速度。

#结论# 没有简单而独特的方法来解决这个问题。我建议您考虑自己的情况并选择上述解决方案。如果您在程序开始时遇到此错误并且您根本无法连接到数据库,则您的连接字符串可能有问题。但是,如果您在与数据库多次成功交互后出现此错误,则问题可能出在连接数上,您可能会考虑更改“wait_timeout”和其他 MySQL 设置或重写代码以减少连接数。

【讨论】:

我只加了wait_timeout,参考dev.mysql.com/doc/refman/5.1/en/… @soheil 没有简单而独特的方法来解决这个问题。当然,但无论如何,你让我很开心。我爱你。 @Soheil 你能添加“暂时禁用 iptables”吗,这是我的问题。 iptables 配置错误,允许将 tcp 数据包发送到 mysql 端口,但阻止 tcp 数据包从同一连接返回。 @Soheil 感谢您的解决方案 - 对我来说,更改 MySQL 配置中的 wait_timeout 参数成功了!初始值仅设置为“300”! 对我来说,它是在 URL jdbc:mysql://localhost:3306/cloudapp?useSSL=false&amp;allowPublicKeyRetrieval=true 的末尾添加 useSSL=false&amp;allowPublicKeyRetrieval=true【参考方案2】:

如果您使用的是 MAMP PRO,这是一个简单的修复方法,我真希望我在开始搜索互联网几天试图解决这个问题之前就已经意识到这一点。真的就是这么简单……

您只需从 MAMP MySQL 选项卡中单击“允许网络访问 MySQL”。

真的,就是这样。

哦,您可能仍必须将绑定地址更改为 0.0.0.0 或 127.0.0.1,如上述帖子中所述,但如果您是 MAMP 用户,则单独单击该框可能会解决您的问题。

【讨论】:

这样做为我节省了很多时间。当我知道这只是一种单层解决方案时,我能感觉到自己达到了沸点。 对我来说,这些端口与 MAMP 在起始页上所说的完全不同。进入 MAMP 首选项并检查端口选项卡以查看您的实际 MySQL 端口是什么。 我的应用程序可以在 Windows 和 Ubuntu 上运行,但不能在装有 MAMP PRO 的 Mac 上运行。这也是我让我的应用在 Mac 上运行的方式。【参考方案3】:

bind-address 设置为服务器的网络 IP 而不是 localhost 默认值,并且为我的用户设置权限对我有用。

我的.cnf:

bind-address = 192.168.123.456

MySql 控制台:

GRANT ALL PRIVILEGES ON dbname.* to username@'%' IDENTIFIED BY 'password';

【讨论】:

或者所有接口都使用0.0.0.0... 回答对我有用,你能描述一下上面 mysql 指令中@'%' 的含义吗? bind-address = 0.0.0.0 为我工作。【参考方案4】:

就我而言,

    /etc/mysql/my.cnf更改远程机器mysql配置:更改 bind-address = 127.0.0.1#bind-address = 127.0.0.1

    在远程机器上,更改 mysql 用户权限 GRANT ALL PRIVILEGES ON *.* TO 'user'@'%' IDENTIFIED BY 'password';

    重要提示:在远程机器上重启mysql:sudo /etc/init.d/mysql restart

【讨论】:

在 Ubuntu/Debian 中安装 MySQL 后,安装过程是安全的,默认情况下会阻止任何外部访问。为了从任何远程机器访问 MySQL,始终需要这些步骤。【参考方案5】:

就我而言(我是菜鸟),我正在测试与 MySQL 建立数据库连接的 Servlet,其中一个异常就是上面提到的那个。

这让我有些头晕目眩,但我意识到这是因为我还没有在localhost 中启动我的 MySQL 服务器。 启动服务器后,问题已解决。

所以,检查 MySQL 服务器是否正常运行

【讨论】:

【参考方案6】:

我刚刚遇到了同样的问题。 发生这种情况是因为 MySQL 守护程序绑定到机器的 IP,这是与有权连接 @your_machine 的用户建立连接所必需的。 在这种情况下,用户应该有权连接 USER_NAME@MACHINE_NAME_OR_IP

我想远程访问我的机器,所以我在 my.cnf 中更改了

bind-address = MY_IP_ADDRESS

bind-address = 0.0.0.0

这将允许来自本地主机甚至外部(在我的情况下)的用户连接到实例。 如果您将 MySQL 绑定到 0.0.0.0,以下两个权限都将起作用:

USER_NAME@MACHINE_NAME_OR_IP

USER_NAME@localhost

【讨论】:

【参考方案7】:

在我的情况下,这是一个空闲超时,导致服务器上的连接断开。连接保持打开状态,但长时间未使用。然后客户端重新启动就可以了,而我相信重新连接也可以。

一个不错的解决方案是让守护程序/服务不时 ping 连接。

【讨论】:

【参考方案8】:

正如上面的详细答案所说,这个错误可能是由很多事情引起的。

我也有这个问题。我的设置是 Mac OSX 10.8,使用 Ubuntu 12.04 的 Vagrant 托管 VirtualBox VM,MySQL 5.5.34。

我在 Vagrant 配置文件中正确设置了端口转发。我可以从我的 Mac 和 VM 中远程登录到 MySQL 实例。所以我知道 MySQL 守护进程正在运行并且可以访问。但是当我尝试通过 JDBC 连接时,我收到了“通信链接失败”错误。

在我的例子中,问题是通过编辑 /etc/mysql/my.cnf 文件解决的。具体来说,我注释掉了“#bind-address=127.0.0.1”这一行。

【讨论】:

你在哪里改的?主机还是 Vagrant MySql? 我在运行 MySQL 的来宾 VM 中进行了配置更改。我不希望 MySQL 直接在我的 Mac 上运行,所以我使用了 VM。【参考方案9】:

Soheil 提供的解决方案对我来说是成功的。

澄清一下,我需要做的唯一更改是 MySQL 的服务器配置;

bind-address = **INSERT-IP-HERE**

我正在为我的应用程序使用外部 MySQL 服务器。这是一个带有 MySQL Server 5.5 的基本 Debian 7.5 安装 - 默认配置。

重要提示:

始终备份您可能修改的任何配置文件的原始文件。提升为超级用户时请务必小心。

文件

/etc/mysql/my.cnf

线

bind-address        = 192.168.0.103 #127.0.0.1

重启你的 MySQL 服务器服务:

/usr/sbin/service mysql restart

如您所见,我只是提供了服务器的网络 IP 并注释掉了默认条目。请注意,简单地复制和粘贴我的解决方案对您不起作用,除非我们的主机奇迹般地共享相同的 IP。

感谢@Soheil

【讨论】:

【参考方案10】:

我知道这是一个旧线程,但我尝试了很多方法并使用以下方法解决了我的问题..

我正在 Windows 上开发一个跨平台应用程序,但要在 Linux 和 Windows 服务器上使用。

两个系统上都安装了一个名为“jtm”的 MySQL 数据库。出于某种原因,在我的代码中,数据库名称为“JTM”。在 Windows 上它运行良好,事实上在几个 Windows 系统上它运行良好。

在 Ubuntu 上,我一次又一次地遇到上述错误。我在代码“jtm”中用正确的大小写对其进行了测试,它很有效。

Linux 显然对区分大小写的容忍度要低得多(这是正确的),而 Windows 则允许。

我现在觉得有点傻,但请检查一切。错误信息不是最好的,但如果你坚持并把事情做对,它似乎是可以修复的。

【讨论】:

Linux 区分大小写【参考方案11】:

如果您在使用一组 Docker 容器时遇到问题,请确保您不仅要 EXPOSE 端口 3306,还要从容器外部映射端口-p 3306:3306。对于docker-compose.yml

version: '2'

services:
    mdb:
        image: mariadb:10.1
        ports:
            - "3306:3306"
        …

【讨论】:

相关,我尝试使用 localhost 或 127.0.0.1 或 0.0.0.0 或固定 ip 进行连接,但需要使用服务名称进行连接(此处:jdbc:mysql://mdb:3306/... 就像@chris.currin 提到的,在从另一个docker_container 访问时提供container_name 很重要。示例"jdbc:mysql://mysql_container:3306/db_name?serverTimezone=UTC&amp;useSSL=false&amp;allowPublicKeyRetrieval=true"【参考方案12】:

我刚刚重新启动了 MySQL(按照这里的提示:https://***.com/a/14238800),它解决了这个问题。

我在通过自制软件安装的 MacOS (10.10.2) 和 MySql (5.6.21) 上遇到了同样的问题。

令人困惑的是,我的一个应用程序连接到数据库正常,而另一个没有。

在应用程序上尝试了许多抛出异常 com.mysql.jdbc.CommunicationsException 的应用程序(如该问题的已接受答案所建议的)无济于事后,我很惊讶重启 MySQL 工作正常。

如上述链接中的答案所示,我的问题的原因可能如下:

你在使用连接池吗?如果是,则尝试重新启动 服务器。您的连接池中可能很少有连接处于关闭状态。

【讨论】:

【参考方案13】:

当没有足够的内存供 MySQL 使用时,就会发生这种情况(在我的情况下)。重新启动会修复它,但如果是这种情况,请考虑使用具有更多内存的机器,或限制 jvms 占用的内存

【讨论】:

限制内存或只是获得更多内存似乎是一种临时解决方案,不是吗?【参考方案14】:

转到控制面板中的 Windows 服务并启动 MySQL 服务。对我来说,它奏效了。当我在做一个 Java EE 项目时,我收到了这个错误“通信链接故障”。我重新启动了我的系统,然后它工作了。

之后,即使重新启动系统,我也再次遇到相同的错误。然后我尝试打开 MySQL 命令行控制台并使用 root 登录,即使这样它也给了我一个错误。

最后,当我从 Windows 服务启动 MySQL 服务时,它工作了。

【讨论】:

【参考方案15】:

也一样。 删除端口对我有帮助,所以我将其保留为 jdbc:mysql://localhost/

【讨论】:

【参考方案16】:

对我来说,解决方案是在 mysql 服务器的 conf 文件中将参数 bind-address="127.0.0.1" 或 bind-address="x.x.x.x" 更改为 bind-address="0.0.0.0"。 谢谢。

【讨论】:

【参考方案17】:

如果你使用的是休眠,这个错误可能是因为保持打开会话对象的时间超过wait_timeout

我在here 记录了一个案例,供感兴趣的人参考。

【讨论】:

【参考方案18】:

我找到了解决办法

因为 MySQL 需要本地主机才能工作。

转到 /etc/network/interfaces 文件并确保在那里设置了 localhost 配置:

auto lo
iface lo inet loopback

现在重新启动网络子系统和 MySQL 服务:

sudo /etc/init.d/networking restart

sudo /etc/init.d/mysql 重启

立即尝试

【讨论】:

不确定 Mac,这在 Linux Debian 上对我有用。 好的。这在更改 MySQL 端口并连接到该新端口后有效。【参考方案19】:

这主要是因为mysql客户端和远程mysql服务器之间的连接较弱。

在我的情况下,这是因为 *** 连接不稳定。

【讨论】:

【参考方案20】:

phpstorm + vagrant autoReconnect 驱动选项有帮助。

【讨论】:

得到:java.sql.SQLException:无法创建与数据库服务器的连接。尝试重新连接 3 次。放弃。【参考方案21】:

我遇到了类似的问题,我的案例的解决方案是

    将绑定地址 = 0.0.0.0 从 127.0.0.1 更改 将 url 的 localhost 更改为 localhost:3306

我觉得我们永远不应该放弃,我尝试了这篇文章和其他论坛的所有选项......很高兴它有效@saurab

【讨论】:

【参考方案22】:

我也遇到过这个问题。

正如 Soheil 所建议的, 我去了路径 C:\windows\php.ini 的 php.ini 文件,然后我修改了这个文件中的端口号。

就行了 mysqli.default_port =.......

所以我在我的 java 应用程序中更改了它,因为它在 php.ini 文件中,现在它适用于我。

【讨论】:

【参考方案23】:

对于 Windows:- 转到开始菜单写入“MySqlserver 实例配置向导”并重新配置您的 mysql 服务器实例。 希望它能解决你的问题。

【讨论】:

【参考方案24】:

多年来遇到同样的问题并且没有永久解决方案,这是过去 3 周解决的问题(这是无错误操作的记录)

设置全局 wait_timeout=3600; 设置全局interactive_timeout=230400;

如果它适合您,请不要忘记将其永久化。

【讨论】:

所以你把这个时间延长了。?有帮助吗【参考方案25】:

如果您使用本地模拟器,则必须使用 IP 地址 10.0.2.2 而不是 localhost 才能访问本地 MySQL 服务器。

【讨论】:

以上是关于使用 JDBC 和 MySQL 解决“通信链路故障”[重复]的主要内容,如果未能解决你的问题,请参考以下文章

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链路故障

.com.mysql.jdbc.exception.jbbc4.communicationexception..通信链路故障

Glassfish4 和 MySQL 5.5.38 远程服务器:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链路故障

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链路故障?

Android:com.mysql.jdbc.exceptions.jdbc4.communicationsexception 通信链路故障

com.mysql.cj.jdbc.exceptions.CommunicationsException:aws cicd 管道构建期间的通信链路故障