首页 文章

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

提问于
浏览
165

这个问题在这里已有答案:

我正在尝试连接到本地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已经注释掉了skip网络选项 .

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

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

25 回答

  • 0

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

    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.
    

    我花了几天时间来解决这个问题 . 我已经测试了许多在不同网站中提到过的方法,但是没有这些方法有效 . 最后我改变了我的代码,发现了问题所在 . 我会试着告诉你不同的方法和 sum them up here .

    当我在寻找互联网找到这个错误的解决方案时,我想出了 there are many solutions that worked for at least one person, but others say that it doesn't work for them! 为什么有很多方法来解决这个错误?好像 this error can occur generally when there is a problem in connecting to the server . 可能问题是由于错误的查询字符串或与数据库的连接太多 .

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

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

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

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

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

    以下是解决方案:

    • changing "bind-address" attribute

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

    绑定地址=“127.0.0.1”

    要么

    绑定地址=“0.0.0.0”

    • commenting out "skip-networking"

    如果MySQL配置文件中存在“跳过网络”行,请在该行的开头添加“#”符号进行注释 .

    • change "wait_timeout" and "interactive_timeout"

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

    wait_timeout =数字

    interactive_timeout =数字

    connect_timeout =数字

    • Make sure Java isn't translating 'localhost' to [:::1] instead of [127.0.0.1]

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

    使用以下两种方法之一可以避免这种情况:

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

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

    export _JAVA_OPTIONS="-Djava.net.preferIPv4Stack=true"
    
    • check Operating System proxy settings, firewalls and anti-virus programs

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

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

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

    在Windows上停止防病毒软件 .

    • change connection string

    检查您的查询字符串 . 您的连接字符串应该是这样的事情:

    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服务器的用户名和密码 .

    • update your JDK driver library file

    • test different JDK and JREs (like JDK 6 and 7)

    • don't change max_allowed_packet

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

    • change tomcat security

    将TOMCAT6_SECURITY = yes更改为TOMCAT6_SECURITY = no

    • use validationQuery property

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

    • AutoReconnect

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

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

    虽然这些解决方案都不适用于我,但我建议你尝试一下 . 因为有些人通过以下步骤解决了他们的问题 .

    But what solved my problem?

    我的问题是我在数据库上有很多SELECT . 每次我创建一个连接然后关闭它 . 虽然我每次关闭连接,但系统面临许多连接并给了我这个错误 . What I did was that I defined my connection variable as a public (or private) variable for whole class and initialized it in the constructor. 然后每次我都使用那个连接 . 它解决了我的问题,也大大提高了我的速度 .

    结论

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

  • 0

    如果你正在使用MAMP PRO,这个简单的解决方案,我真的希望在我开始搜索互联网几天之前我已经意识到这一点 . 真的很简单......

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

    真的,就是这样 .

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

  • 5

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

    my.cnf文件:

    bind-address = 192.168.123.456
    

    MySql控制台:

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

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

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

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

    就我而言,通过编辑/etc/mysql/my.cnf文件解决了问题 . 具体来说,我注释掉了“#bind-address = 127.0.0.1”这一行 .

  • 0

    在我的情况下,这是一个空闲超时,导致连接被丢弃在服务器上 . 连接保持打开状态,但长时间不使用 . 然后客户端重启工作,而我相信重新连接也会工作 .

    一个不错的解决方案是有一个守护进程/服务来不时ping连接 .

  • 2

    就我而言,

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

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

    • 重要说明:在远程计算机上重启mysql: sudo /etc/init.d/mysql restart

  • 1

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

  • 0

    我刚遇到同样的问题 . 之所以发生这种情况,是因为MySQL守护程序绑定到了计算机的IP,这需要与有权连接@your_machine的用户 Build 连接 . 在这种情况下,用户应该有权连接USER_NAME @ MACHINE_NAME_OR_IP

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

    bind-address = MY_IP_ADDRESS
    

    bind-address = 0.0.0.0
    

    这将允许来自localhost甚至外部(在我的情况下)的用户连接到该实例 . 如果将MySQL绑定到0.0.0.0,则以下权限都将起作用:

    USER_NAME@MACHINE_NAME_OR_IP
    
    USER_NAME@localhost
    
  • 1

    在我的情况下(我是一个菜鸟),我正在测试与MySQL Build 数据库连接的Servlet,其中一个例外是上面提到的 .

    它使我的头部摇摆了几秒钟,但我开始意识到这是因为 I have not started my MySQL server in localhost .
    启动服务器后,问题得到解决 .

    所以, check whether MySQL server is running properly .

  • 0

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

  • 0

    转到控制面板中的Windows服务并启动MySQL服务 . 对我来说它有效 . 当我做Java EE项目时,我收到此错误“通信链接失败” . 我重新启动了我的系统然后它工作了 .

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

    最后,当我从Windows服务启动MySQL服务时,它工作正常 .

  • 0

    有同样的 . 在我的情况下删除端口有帮助,所以我把它留作jdbc:mysql:// localhost /

  • 0

    如果您正在使用hibernate,则可能会因为保持打开Session对象的时间超过 wait_timeout 而导致此错误

    我已经为here记录了一个案例感兴趣 .

  • 0

    I found the solution

    因为MySQL需要Localhost才能正常工作 .

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

    auto lo
    iface lo inet loopback
    

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

    sudo /etc/init.d/networking restart

    sudo /etc/init.d/mysql restart

    现在就试试

  • 1

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

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

  • -3

    在phpstorm vagrant autoReconnect驱动程序选项帮助 .

  • 0

    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 Server服务:

    /usr/sbin/service mysql restart
    

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

    谢谢@ Soheil

  • 0

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

    • 从127.0.0.1更改bind-address = 0.0.0.0

    • 将url的localhost更改为localhost:3306

    我觉得我们永远不应该放弃,我尝试了这篇文章以及其他论坛的所有选项......快乐它的作品@saurab

  • 0

    我也遇到了这个问题 .

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

    它在线mysqli.default_port = ..........

    所以我在我的java应用程序中更改了它,因为它在php.ini文件中,现在它可以正常使用我 .

  • 0

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

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

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

    在Ubuntu上我一次又一次地得到了错误 . 我在代码“jtm”中使用正确的案例对其进行了测试,并且它有效 .

    对于区分大小写,Linux显然不那么宽容(这是正确的),而Windows则允许 .

    我觉得现在有点蠢,但检查一切 . 错误信息并不是最好的,但如果你坚持不懈并且把事情做好,它似乎确实可以修复 .

  • 0

    I just restarted MySQL (following a tip from here: https://stackoverflow.com/a/14238800) and it solved the issue.

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

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

    在应用程序上尝试了很多东西,抛出了这个问题的接受答案所建议的异常com.mysql.jdbc.CommunicationsException无济于事,我很惊讶重启MySQL工作 .

    我的问题的原因可能如上述链接中的答案中所建议的那样:

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

  • 12

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

  • 0

    多年来有同样的问题,没有永久的解决方案,这是过去3周解决了什么(这是无误操作的记录)

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

    如果适合您,请不要忘记永久保留 .

  • 327

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

    version: '2'
    
    services:
        mdb:
            image: mariadb:10.1
            ports:
                - "3306:3306"
            …
    
  • 3

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

相关问题