com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链接失败


225

我正在努力使数据库与Java程序进行通讯。

有人可以使用JDBC给我一个快速而肮脏的示例程序吗?

我收到一个相当惊人的错误:

Exception in thread "main" 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:409)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1122)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2260)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:787)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:49)
    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:409)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:357)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
    at java.sql.DriverManager.getConnection(DriverManager.java:582)
    at java.sql.DriverManager.getConnection(DriverManager.java:207)
    at SqlTest.main(SqlTest.java:22)
Caused by: 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:409)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1122)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:344)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2181)
    ... 12 more
Caused by: java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)
    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:256)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:293)
    ... 13 more

测试文件内容:

import com.mysql.jdbc.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SqlTest {

    public static void main(String [] args) throws Exception {
        // Class.forName( "com.mysql.jdbc.Driver" ); // do this in init
        // // edit the jdbc url 
        Connection conn = DriverManager.getConnection( 
            "jdbc:mysql://localhost:3306/projects?user=user1&password=123");
        // Statement st = conn.createStatement();
        // ResultSet rs = st.executeQuery( "select * from table" );

        System.out.println("Connected?");
    }
}

17
我真傻。MySQL服务器未启动:(启动后成功
。– akfaisel

Answers:


251

所以,你有一个

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链接失败
java.net.ConnectException:连接被拒绝

我引用了这个答案,其中还包含一个逐步的MySQL + JDBC教程:

如果您使用SQLException: Connection refusedConnection timed out或MySQL特定的CommunicationsException: Communications link failure,则意味着该数据库根本无法访问。可能有以下一种或多种原因:

  1. JDBC URL中的IP地址或主机名错误。
  2. 本地DNS服务器无法识别JDBC URL中的主机名。
  3. JDBC URL中的端口号丢失或错误。
  4. 数据库服务器已关闭。
  5. DB服务器不接受TCP / IP连接。
  6. 数据库服务器已用尽连接。
  7. Java和DB之间的某种事物正在阻止连接,例如防火墙或代理。

要解决一个或另一个,请遵循以下建议:

  1. 使用验证并测试它们ping
  2. 刷新DNS或在JDBC URL中使用IP地址。
  3. 验证基于my.cnfMySQL DB。
  4. 启动数据库。
  5. 验证mysqld是否在不带的情况下启动--skip-networking option
  6. 重新启动数据库并相应地修复您的代码,使其关闭中的连接finally
  7. 禁用防火墙和/或配置防火墙/代理以允许/转发端口。

也可以看看:


4
MAMP / MAMP Pro默认设置MAMP_skip-networking_MAMP。您必须在my.cfn中禁用此行
Jurik 2013年

6
并非在这种情况下,但是当您使用连接池并且由于长时间不活动而关闭连接时,也会发生通信链接故障。仅在这种情况下,它说“最后一个数据包在几秒钟前就收到了” X””
nikel,2015年

@nikel是否应该通过触发“选择1”验证查询来保持连接池中的线程处于活动状态?当我们将退出者设置为比mysql服务器超时的时间间隔短时,为什么长时间不活动会关闭它们?
Farhad

是的,验证查询可以解决此问题。我的观点是关于未设置该设置以及池中的连接由于不活动而超时的情况
nikel,2016年

有时连接字符串中缺少端口,驱动程序将尝试连接到默认的3306 mysql端口,如果mysql未在此端口上运行,则驱动程序将失败。这是我的问题,所以我虽然应该提一下,以防其他人发现它有用。
Abdul Mannan

10

当Java堆满时,我捕获了此异常。如果我尝试在RAM中放入许多数据项-首先,我会遇到“ 通信链接失败 ”,然后是“ OutOfMemoryError ”。

我记录了下来,减少了内存消耗(删除1/2数据),一切正常。


9

就我而言,我需要将Localhost替换为实际的数据库服务器IP地址

代替

 Connection con = DriverManager.getConnection(
 "jdbc:mysql://localhost:3306/DBname", "root", "root");

我需要

 Connection con = DriverManager.getConnection(
 "jdbc:mysql://192.100.0.000:3306/DBname", "root", "root");

在最新更新4/5/18上:当前,我正在使用MySQL Workbench 6.3。我来这里是为了检查解决方案,但我自己找到了它,只是您的MySQL服务器未运行或已停止。我重新启动了服务器,它像一个魅力一样工作。
Abhishek Ekaanth'4

7
这是“最佳解决方案”的原因吗?它解决什么问题,以及如何解决?
罗恩侯爵'18年

此解决方案无法生成数据帧
Alan

8

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException如果您的数据库连接长时间处于空闲状态,则会发生此异常。

该空闲连接在打开时返回true,connection.isClosed();但是如果我们尝试执行语句,则它将触发此异常,因此我建议使用数据库池。


2
它也由于其他原因而发生,例如“连接被拒绝”。
罗恩侯爵'18年

6

我几个小时来一直遇到同样的问题。我正在使用MAMP Server

不要使用localhost:[Apache Port],而要使用MySQL端口。

以下是MAMP服务器的默认MySQL端口。

String url = "jdbc:mysql://localhost:8889/db_name";

Connection conn = DriverManager.getConnection(url, dbUsername, dbPassword);

如果您在安装Mysql之前安装了
Mamp,请

5

我可能在这里拨错了树,但是您的异常似乎表明您的MySQL服务器不可用。

线程“ main”中的异常com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链接失败最后一次成功发送到服务器的数据包是在0毫秒前。驱动程序尚未收到来自服务器的任何数据包。在...

如果尝试(从终端)会发生什么?

mysql -u username -p

系统将提示您输入与用户名关联的密码。输入正确的密码后,mysql客户端会连接吗?

如果没有,则可能必须从“首选项”启动MySQL。您还可以将其设置为在启动时运行。


1
我正在使用MAMP运行我的MySQL服务器。那会是个问题吗?
乔什·K

当我通过Sequal Pro连接到我时,localhost我使用正确的用户名/密码,并且可以正常工作。
乔什·K

5

就我而言,原来是的版本mysql-connector-java太旧。

在我的演示中,我以某种方式使用mysql-connector-java

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.9</version>
</dependency>

但是在开发环境中,我使用以下代码:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.31</version>
</dependency>

我的MySQL版本是5.1.48(是的,它很旧,仅用于模拟产品版本)。所以我遇到了同样的错误。

由于找到了原因,所以也找到了解决方案。匹配版本!


4
不太可能。所有这些驱动程序版本都应该向后兼容。
罗恩侯爵

1
这个问题似乎已在新的mysql连接器中解决,请参见stackoverflow.com/questions/14559794/…–
Nishi

对我来说也是一样。驱动程序的版本适用于MySQL 5,而服务器的版本则适用于8。因此,我更新了jar的版本,并解决了问题。
edenPan

4

我遇到了同样的错误,因为我试图在不启动mysql服务器的情况下运行程序。

启动mysql服务器后,一切正常。


4

较早的答案是适当的。但是,我也想指出一个更通用的问题。

我遇到了类似的问题,原因是我公司的网络限制。

当我在任何其他网络中时,相同的连接正在成功。


1
该指针解决了我的问题,指定当我连接到VPN时“本地主机”正在工作,但是如果我断开与VPN的连接,则无法正常工作,但是我通过将“本地主机”更改为“ 127.0.0.1”来解决此问题
gannu_lee

4

请在/etc/mysql/my.cnf文件中更新您的IP地址

bind-address  = 0.0.0.0

重新启动mysql守护进程和mysql服务。


1
编辑为使用有效的绑定地址
OneCricketeer

3

下载的MySQL-JDBC型-4-二极管驱动器(IG 'MySQL的连接器的Java-5.1.11-bin.jar'从'mysql-connector-java-5.1.11.zip')在Mysql的

您需要在类路径的编译和运行时灌输驱动程序jar。

Class.forName( "com.mysql.jdbc.Driver" ); // do this in init
// edit the jdbc url 
Connection conn = DriverManager.getConnection( "jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName", username, password );
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery( "select * from table" );

不,给我一个关于找不到任何东西的错误风暴。无需JAR文件就可以导入吗?
乔什·K

@Josh这行得通,实际上您只需要正确设置类路径即可。(或将jar复制到您的%JAVA_HOME%\ jre \ lib \ ext目录中,但这是不正确的做法)
堆垛机2010年

3

如果Java尝试通过SSL连接到MySQL,也可能会发生此错误,但是出了点问题。(就我而言,我正在配置与MySQL的Payara Server 5.193.1连接池。)

有人建议设置useSSL=false。但是,由于是Connector / J版本8.0.13,因此不赞成使用该设置。这是MySQL Connector / J 8.0配置属性的摘录:

sslMode

默认情况下,网络连接是SSL加密的;此属性允许关闭安全连接,或选择其他级别的安全性。允许以下值:DISABLED-建立未加密的连接;PREFERRED-(默认)如果服务器启用了加密连接,则建立它们,否则退回到未加密的连接;REQUIRED-如果服务器启用了安全连接,则建立安全连接,否则失败;VERIFY_CA-与REQUIRED配置的证书颁发机构(CA)证书类似但另外验证服务器TLS证书;VERIFY_IDENTITY-与相似VERIFY_CA,但另外请验证服务器证书是否与尝试连接的主机匹配。

此属性替换已过时的旧属性useSSLrequireSSL以及verifyServerCertificate,对目前仍在接受,但翻译成一个值sslMode,如果sslMode未明确设置:useSSL=false被翻译成sslMode=DISABLED; {"useSSL=true", "requireSSL=false", "verifyServerCertificate=false"}被翻译成sslMode=PREFERRED; {"useSSL=true", "requireSSL=true", "verifyServerCertificate=false"}被翻译成sslMode=REQUIRED; {"useSSL=true" AND "verifyServerCertificate=true"}被翻译成sslMode=VERIFY_CA。没有等效的旧版设置sslMode=VERIFY_IDENTITY。请注意,对于所有服务器版本,默认设置sslModePREFERRED,它等效于的旧设置useSSL=true,在某些情况下,其与Connector / J 8.0.12及更低版本的默认设置不同。继续使用旧属性并依赖其旧的默认设置的应用程序应进行检查。requireSSL=falseverifyServerCertificate=false

如果sslMode显式设置,则遗留属性将被忽略。如果未明确设置sslModeuseSSL,则应用默认设置sslMode=PREFERRED

默认值PREFERRED

从版本:8.0.13

因此,就我而言,sslMode=DISABLED解决问题只需要设置即可。这是在测试机上。但是对于生产而言,安全的解决方案是正确配置Java客户端和MySQL服务器以使用SSL。


请注意,通过禁用SSL,您可能还需要设置allowPublicKeyRetrieval=true。(再次,从安全角度来看,这不是明智的决定)。MySQL ConnectionString Options中提供了更多信息:

AllowPublicKeyRetrieval

如果用户帐户使用sha256_password身份验证,则在传输过程中必须保护密码。TLS是实现此目的的首选机制,但是如果它不可用,则将使用RSA公钥加密。要指定服务器的RSA公钥,请使用ServerRSAPublicKeyFile连接字符串设置,或设置AllowPublicKeyRetrieval=True为允许客户端自动从服务器请求公钥。请注意,这AllowPublicKeyRetrieval=True可能允许恶意代理执行MITM攻击以获取纯文本密码,因此默认情况下为False,必须明确启用它。


来自Payara Server GitHub的相关线程。
MS Dousti

3

我的相同问题可以通过以下步骤解决:

  1. my.cnf

    vi /etc/mysql/my.cnf
  2. 修改其绑定地址

    "bind-address = 0.0.0.0"
  3. 重新启动MySQL

    sudo /etc/init.d/mysql restart

2

如果使用服务器WAMPXAMP服务器来安装mysql数据库。然后,您必须以其他方式显式启动mysql服务器,否则它将com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure在与数据库连接时显示


2

我以一种简单的方式解决了这个问题,这对我有用。我遇到了一个问题:“ com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链接失败”。在我的db.properties文件中,我有:url:jdbc:mysql:// localhost:90 / myDB,仅删除了端口url,以这种方式产生了url:jdbc:mysql:// localhost / myDB,这对我有用。


2

当我将my.ini和php.ini文件中的mysql端口从3306更改为3307时,事情就发生了,但是更改端口(3307-> 3306)后,它又可以正常工作了。


2

如果更改了端口,则会出现这种错误“ com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链接失败”,请检查您的端口号


1

刚刚经历过。

通过以下方式使其起作用:(可以将其放置在静态块初始化器中)

static{ // would have to be surrounded by try catch
    Class.forName("com.mysql.jdbc.Driver");   // this will load the class Driver
}

也可以通过以下方式获得连接:

conn = DriverManager.getConnection(DBURL,<username>,<password>);

而不是指定登录参数

  Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/projects?user=user1&password=123");

问候。


2
自2007年以来,就不再需要使用静态块了,您可以通过两种方式指定登录参数。
罗恩侯爵

1

尝试更改localhost127.0.0.1

本地主机将解析为::1。默认情况下,MySQL无法通过IPv6连接。

这是输出telnet localhost 3306

$ telnet localhost 3306
Trying ::1...

而且MySQL服务器没有响应。

当然,请确保您的MySQL服务器正在运行。


这实际上是您的/ etc / hosts文件的问题,而不是Mysql的问题
OneCricketeer

@ cricket_007默认情况下,本地主机解析为:: 1而不是127.0.0.1。

1
当然,只有启用ipv6并取决于主机文件时
OneCricketeer

1
dbhost=jdbc:mysql://172.18.23.100:3306/yourdatabase?useUnicode=yes&characterEncoding=UTF-8&useSSL=false
user=root
password=Password#321

con = DriverManager.getConnection(dbhost, user, password);

如果mysql版本8或更高版本的用户更新了连接器


这是正确的答案,只需在使用MySQL驱动程序8或更高版本时将useSSL = false添加到连接字符串即可。
Mohannd

1

对于远程调用Mysql

  1. 通过示例IP = remoteIP 将远程用户添加到Mysql中

    mysql -u xxxx -p //local coonection to mysql
    mysql> GRANT ALL PRIVILEGES ON *.* TO 'theNewUser'@'remoteIP' IDENTIFIED BY 'passWord';
    //Query OK, 0 rows affected (xx sec)
    mysql> FLUSH PRIVILEGES;
    //Query OK, 0 rows affected
  2. 允许远程访问 Mysql(默认情况下,不允许所有外部调用):

    Edit 
    /etc/mysql/mysql.conf.d/mysqld.cnf    or    /etc/mysql/my.cnf
    Change line:  bind-address = 127.0.0.1   to
                  bind-address = 0.0.0.0
    Restart Mysql: /etc/init.d/mysql restart
  3. 对于最新版本的JDBC驱动程序,JDBC:

    jdbc.url='jdbc:mysql://remoteIP:3306/yourDbInstance?autoReconnect=true&amp;useUnicode=true&amp;useJDBCCompliantTimezoneShift=true&amp;useLegacyDatetimeCode=false&amp;serverTimezone=UTC'
    jdbc.user='theNewUser'

0

我遇到了同样的问题,这是解决问题的方法:

  1. 我的.jsp正在调用我尚未在servlet中定义的属性。
  2. 我有两个要传递给对象ResultSet (getString("columnName"))的列名与数据库中的列名不匹配。

我不确定是哪一个解决了问题,但是确实有效。此外,要确保你创建一个新的Statement并且ResultSet对每个表查询。


1
(1)当然不会造成这个问题。
罗恩侯爵'18年

0

这可能是一个简单的jar问题。可能是您使用的mysql-connector-java-XXX-bin.jar是您当前的mysql版本不支持的旧版本。我使用的 mysql-connector-java-5.1.18-bin.jar是我所使用的mysql 5.5,这个问题已为我解决。


1
是的,罐子可能不匹配。
Kiran Nunna

所有这些驱动程序版本都应该兼容。
罗恩侯爵

0

也许您没有启动Mysql和Apache Server。从XAMPP控制面板启动Apache服务器和Mysql之后,连接成功建立。

祝好运!


0

为我解决的是做两件事:1.使用以下几点用root用户创建一个新用户,而不是root用户:

CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'newuser'@'localhost';
FLUSH PRIVILEGES;

2.在mysqld.conf上注释IP地址行

然后使用新的用户名和密码进行连接。它应该工作。


您需要为所有远程用户重复此操作,或者添加通配符而不是Localhost
OneCricketeer

0

它试图连接到旧版本的MySQL('version','5.1.73'); 当您使用较新的驱动程序版本时,会收到一条错误消息,提示您使用“ com.mysql.cj.jdbc.Driver”,甚至不必指定要使用的驱动程序:

正在加载com.mysql.jdbc.Driver'. This is deprecated. The new driver class iscom.mysql.cj.jdbc.Driver 类。通过SPI自动注册驱动程序,通常不需要手动加载驱动程序类。

我将声明更改为使用mysql-connector-java的5.1.38版本,并且在代码中保留了com.mysql.jdbc.Driver

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.38</version>
</dependency>

当我看到Ankit Jain的回答时,一切都开始了



0

在我的MacBook中,仅当重新安装新版本的eclipse EE并删除本地服务器(如xamp mysql或mamp)但仅使用其中一个时,我才解决此错误。


0

以我为例,我必须建立到远程数据库的ssh隧道,并且所有设置都是正确的,并且与PhpStorm的连接测试也成功。并且还加载了架构,但未加载数据。相反,我得到了:

[08S01] 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.

上面的建议均无效。无论出于什么原因,我都试图通过简单地重新启动PhpStorm来解决问题,瞧!


0

我收到多个错误,例如:

  • CommunicationsException: Communications link failure
  • java.lang.NullPointerException: Attempt to invoke interface method 'java.sql.Statement java.sql.Connection.createStatement()' on a null object reference at

我必须添加:

  • 在AndroidManifest.xml中<uses-permission android:name="android.permission.INTERNET"/>,在开始清单标记之后包含。

  • 将JDBC驱动程序添加到您的Gradle(或Maven)依赖项中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.