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

Jos*_*h K 200 java mysql jdbc

我正在努力让我的数据库与我的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
Run Code Online (Sandbox Code Playgroud)

测试文件的内容:

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?");
    }
}
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 231

所以,你有一个

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

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

如果您获得SQLException: Connection refusedConnection timed out特定于MySQL CommunicationsException: Communications link failure,则意味着DB根本无法访问.这可能有以下一个或多个原因:

  1. JDBC URL中的IP地址或主机名是错误的.
  2. 本地DNS服务器无法识别JDBC URL中的主机名.
  3. JDBC URL中的端口号丢失或错误.
  4. 数据库服务器已关闭.
  5. 数据库服务器不接受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. 禁用防火墙和/或配置防火墙/代理以允许/转发端口.

也可以看看:

  • 不是在这种情况下,但是当您使用连接池并且由于长时间不活动而关闭连接时,也会发生通信链路故障.只有在这种情况下,它说"最后一个包收到了一些"X"秒前" (5认同)
  • MAMP/MAMP Pro默认设置MAMP_skip-networking_MAMP.你必须在你的my.cfn中禁用这一行 (4认同)

Ger*_*ser 30

就我而言,解决方案是将预期的 TLS 协议添加到连接字符串中,如下所示:

jdbc:mysql://localhost:3306/database_name?enabledTLSProtocols=TLSv1.2
Run Code Online (Sandbox Code Playgroud)

出于测试/开发目的(不建议用于生产),您还可以尝试:

jdbc:mysql://localhost:3306/database_name?useSSL=false&allowPublicKeyRetrieval=true
Run Code Online (Sandbox Code Playgroud)


小智 10

这是最好的解决方案,

 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");
Run Code Online (Sandbox Code Playgroud)

将Localhost替换为您的IP地址

  • 这是'最佳解决方案'为什么?它解决了什么问题,怎么解决? (6认同)

use*_*306 9

当Java出堆时我抓住了这个异常.如果我尝试在RAM中放入许多数据项 - 首先我捕获" 通信链接失败 "和下一个" OutOfMemoryError ".

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


小智 9

添加此 useSSL=false&allowPublicKeyRetrieval=true

jdbc:mysql://localhost:3306/cloudapp?useSSL=false&allowPublicKeyRetrieval=true

https://youtu.be/ray3YvnIohM


M.S*_*sti 8

如果 Java 尝试通过 SSL 连接到 MySQL,但出现问题,也可能会发生此错误。(在我的例子中,我正在配置 Payara Server 5.193.1 连接池到 MySQL。)

\n

有人建议设置useSSL=false。但是,从 Connector/J 版本开始8.0.13,该设置已被弃用。以下是MySQL Connector/J 8.0 配置属性的摘录:

\n
\n

SSL模式

\n

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

\n

此属性取代了已弃用的旧属性useSSLrequireSSLverifyServerCertificate,它们仍然被接受,但转换为一个值,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=truerequireSSL=false、 和的旧设置verifyServerCertificate=false,在某些情况下与 Connector/J 8.0.12 及更早版本的默认设置不同。应审查继续使用旧属性并依赖于旧默认设置的应用程序。

\n

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

\n

默认PREFERRED

\n

自版本:8.0.13

\n
\n

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

\n
\n

请注意,通过禁用 SSL,您可能还必须设置allowPublicKeyRetrieval=true. (同样,从安全角度来看,这不是一个明智的决定)。MySQL ConnectionString 选项中提供了更多信息:

\n
\n

允许公钥检索

\n

如果用户账户使用sha256_password认证,则密码在传输过程中必须受到保护;TLS 是首选机制,但如果不可用,则将使用 RSA 公钥加密。要指定 server\xe2\x80\x99s RSA 公钥,请使用ServerRSAPublicKeyFile连接字符串设置,或设置AllowPublicKeyRetrieval=True为允许客户端自动向服务器请求公钥。请注意,这AllowPublicKeyRetrieval=True可能允许恶意代理执行 MITM 攻击以获取明文密码,因此默认情况下为 False,并且必须显式启用。

\n
\n


小智 7

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

这个空闲连接返回true,connection.isClosed();但如果我们尝试执行语句,那么它将触发此异常,因此我建议使用数据库池.

  • 它也会因其他原因而发生,例如“连接被拒绝”。 (2认同)

use*_*882 6

先前的答案是适当的。但是,我还想指出一个更普遍的问题。

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

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


Kar*_*lsh 5

我可能在这里咆哮错误的树,但你的异常似乎表明你的MySQL服务器不可用.

线程"main"中的异常com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链路故障成功发送到服务器的最后一个数据包是0毫秒前.驱动程序未收到来自服务器的任何数据包.在...

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

mysql -u username -p
Run Code Online (Sandbox Code Playgroud)

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

如果没有,您可能必须从首选项启动MySQL.您也可以将其设置为在启动时运行.


小智 5

几个小时我一直有同样的问题.我正在使用MAMP服务器

而不是使用localhost:[Apache Port],使用您的MySQL端口.

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

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

Connection conn = DriverManager.getConnection(url, dbUsername, dbPassword);
Run Code Online (Sandbox Code Playgroud)


she*_*bye 5

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

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

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.9</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

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

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.31</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

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

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

  • 不太可能。所有这些驱动程序版本都应该向后兼容。 (3认同)