使用 JDBC 访问远程 MySQL 数据库时出现 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException

Posted

技术标签:

【中文标题】使用 JDBC 访问远程 MySQL 数据库时出现 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException【英文标题】:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException when using JDBC to access remote MySQL database 【发布时间】:2010-12-31 12:13:28 【问题描述】:
/**
 * 
 */
package ORM;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @author Gwilym
 * @version 0.0
 */
public class DatabaseConnection 

 private  String userName="";
 private  String password="";
 private  String host="";
 Connection conn;

/**
  * @param userName
  * @param password
  * @param host
  */
 public DatabaseConnection(String userName, String password, String host) 
  this.userName = userName;
  this.password = password;
  this.host = host;
 

 public DatabaseConnection(String userName, String password, String host,boolean autoConnect) 
  this.userName = userName;
  this.password = password;
  this.host = host;
  if (autoConnect)
  
  try 
   Connect();
   catch (DatabaseConnectionException e) 
   e.printStackTrace();
   
  
 

/**
  * @return the connection
  */
 public Connection getConn() 
  return conn;
 

 /**
  * @param userName the userName to set
  */
 public void setUserName(String userName) 
  this.userName = userName;
 

 /**
  * @param password the password to set
  */
 public void setPassword(String password) 
  this.password = password;
 

 /**
  * @param host the host to set
  */
 public void setHost(String host) 
  this.host = host;
 

/**
 * Connect, attempts to connect to the mysql database
 * with sun JDBC 
 * & MySQL driver
 * @param none
 * @return True iff connected;
 * @return False for all else;
 * @throws DatabaseConnectionException 
 */
public boolean Connect() throws DatabaseConnectionException

 // Attempt to load database driver
 try
    
        String url = "jdbc:mysql:"+host;
        System.out.println(url);
        //Load driver
        Class.forName ("com.mysql.jdbc.Driver").newInstance ();

        conn = DriverManager.getConnection (url, userName, password);
    
 catch (ClassNotFoundException cnfe) // driver not found
 
  conn=null;
  System.err.println ("Unable to load database driver");
  throw new DatabaseConnectionException(cnfe);
  
 catch(InstantiationException ie)
 
  conn=null;
  System.err.println ("Unable to Create database driver");
  throw new DatabaseConnectionException(ie); 
 
 catch (IllegalAccessException iae)
 
  conn=null;
  System.err.println ("Unable to Create database driver");
  throw new DatabaseConnectionException(iae);
  catch (SQLException sqle) 
  conn=null;
  System.err.println ("SQL error");
  throw new DatabaseConnectionException(sqle);
 

    if (conn!=null)
    
        System.out.println ("Database connection established"); 
        return true;
    
    else
    
     System.out.println ("Database connection Failed"); 
        return false;
    




/**
 * Disconnects the System from the mySQL database
 * 
 * @param none
 * @return true, if successful
 * @return false if not connection in existance 
 */
public boolean Disconnect()

 if (conn != null)
    
        try
        
            conn.close ();
            conn=null;
            System.out.println ("Database connection terminated normally");
            return true;
        
        catch (Exception e) 
       //Ignore these errors as they all result in conn.close anyway
        
        finally
        
        conn=null;
        System.gc();
        // my removing the refrance to conncetion all calling the Garbage collecter we insure it is destoryed.
        
        System.out.println ("Database connection terminated with errors");
        return true;    
    
 else
 
  System.out.println ("No Database connection present");
        return true;    
 






以上代码由

调用
DatabaseConnection db =new DatabaseConnection("USERNAME","PASSWORD","//tel2.dur.ac.uk:3306/dcs8s07_SEG",true);

出于显而易见的原因,我删除了用户名和密码,但可以认为它们是正确的。

就问题本身而言,我得到一个 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException,当此代码运行时,详细信息“最后一个成功发送到服务器的数据包是 0 毫秒前。驱动程序有没有收到来自服务器的任何数据包。”

我目前的主要问题是试图找出实际出了什么问题。

据我所知,驱动程序正在正确加载,因为我的代码没有抛出 ClassNotFoundException,而是某种 SQLException。

所以问题几乎可以肯定是某种方式的连接。我可以通过位于同一台服务器上的 phpMyadmin 连接和查询该数据库,因此我可以假设

1)服务器在线 2)mysql正在工作 3)用户名和密码正确 4) 数据库存在并且我的名称正确

从此和“驱动程序没有收到来自服务器的任何数据包。”我想知道 URL 是否格式错误?

URL= jdbc:mysql://tel2.dur.ac.uk:3306/dcs8s07_SEG

或者服务器上有一个不正确的简单设置不允许我连接?

我已经思考过这个问题并尝试了几次谷歌都无济于事,所以任何想法都会有很大帮助

提前致谢!

【问题讨论】:

【参考方案1】:

这是一个包装异常。此异常的根本原因是什么?进一步查看堆栈跟踪。

一个非常常见的根本原因是java.net.ConnectException: Connection refused。我在几乎 99% 的案例中都看到了这一点。如果您的情况也是如此,那么所有可能的原因是:

    JDBC URL 中的 IP 地址或主机名错误。 本地 DNS 服务器无法识别 JDBC URL 中的主机名。 JDBC URL 中的端口号缺失或错误。 数据库服务器已关闭。 数据库服务器不接受 TCP/IP 连接。 Java 和 DB 之间的某些东西阻塞了连接,例如防火墙或代理。

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

    使用ping 验证和测试它们。 刷新 DNS 或改用 JDBC URL 中的 IP 地址。 根据 MySQL DB 的my.cnf 进行验证。 开始吧。 验证 mysqld 是否在没有 --skip-networking 选项的情况下启动。 禁用防火墙和/或配置防火墙/代理以允许/转发端口。

用户名和密码与此问题无关。此时甚至无法访问数据库。否则,您将收到“登录失败”或“未授权”SQLException

【讨论】:

嘿巴劳斯我有一些非常接近的原因:java.net.ConnectException:连接超时:连接 连接超时usu。表示防火墙正在阻止通信。 嘿 argherna 你觉得哪边?我的电脑还是服务器? 只是 shh'd 到同一网络上的服务器并对其进行 ping 操作,所以看起来它是我所有血腥事物的防火墙 把我的防火墙关了还是不高兴【参考方案2】:

除了上一篇文章之外,您还应该进行低级 telnet 测试,这是验证连接性的最佳方法。该测试将告诉您是否有防火墙或其他软件阻止访问该端口。

telnet tel2.dur.ac.uk 3306

【讨论】:

我得到了一些有趣的结果,我 ping 了它并得到了 C:\Users\Panda>ping tel2.dur.ac.uk Ping tel2.dur.ac.uk [129.234.200.251] 与 32数据字节:请求超时。请求超时。请求超时。请求超时。 129.234.200.251 的 Ping 统计信息:数据包:发送 = 4,接收 = 0,丢失 = 4(100% 丢失),但我仍然可以通过 http 访问 phpMyadmin telnet tel2.dur.ac.uk 3306 命令在我将它弹出到 cmd 时不起作用 那听起来好像端口被阻塞了,你有没有控制这台主机和它周围的防火墙? 只是 shh'd 到同一网络上的服务器并 ping 它,所以看起来它是我的防火墙,但我关闭了我唯一拥有的窗口,但仍然得到相同的异常 关闭防火墙后,telnet连接正常吗?如果是这样,请加载 mysql 命令行工具并尝试与之连接。如果可行,那么您就知道问题出在您的配置上,而不是您的网络上。

以上是关于使用 JDBC 访问远程 MySQL 数据库时出现 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException的主要内容,如果未能解决你的问题,请参考以下文章

使用 JDBC 连接到 MySQL 数据库时出现问题

在 Hortonworks 上使用 Jdbc 远程连接到 Hive 时出现 ClassNotFoundException

使用 JDBC 获取与 MySQL 的连接时出现“连接过多”

使用 mysql 运行 JDBC 程序时出现此错误 [重复]

使用 JDBC 连接器 5.1 从 Java 读取/写入 MySQL 中的 UTF-8 数据时出现问题

将 spark 应用程序连接到远程 sql 服务器时出现 jdbc 连接超时错误