使用 JDBC 和 MySQL 解决“通信链路故障”以下是解决方案:

2022-08-31 05:34:28

我正在尝试连接到本地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 connector 5.1.17

我确保用户有权访问我的数据库。


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

我花了几天时间解决这个问题。我已经测试了许多在不同网站中提到的方法,但没有一个有效。最后,我更改了代码并找出了问题所在。我将尝试告诉您不同的方法并在此处进行总结

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

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

以下是我在互联网上找到的解决方案,对于每个解决方案,至少有人用该解决方案解决了他的问题。

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

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

  • Windows:(请注意,这是程序数据,而不是程序文件)C:\**ProgramData**\MySQL\MySQL Server 5.6\my.ini

以下是解决方案:

  • 更改属性:bind-address

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

     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.1IPv4:::1 (IPv6)

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

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

    2. 运行 java,并可以选择强制使用 java 而不是 。在Linux上,这也可以通过运行(或将其放在内部)来实现:-Djava.net.preferIPv4Stack=trueIPv4IPv6/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";
    

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

尝试将“本地主机”替换为环回地址 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_packet

"max_allowed_packet“是MySQL配置文件中的一个变量,指示最大数据包大小,而不是最大数据包数。因此,解决此错误无济于事。

  • 更改雄猫安全性

将 TOMCAT6_SECURITY=是 更改为 TOMCAT6_SECURITY=否

  • 使用验证查询属性

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

  • 自动重新连接

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

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

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

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

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

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


答案 2

如果您使用的是MAMP PRO,那么简单的修复方法,我真的希望在我开始搜索互联网几天试图弄清楚这一点之前已经意识到了这一点。它真的这么简单...

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

真的,就是这样。

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


推荐