Java程序连接GCP MySQL实例报SQLNonTransientConnectionException错误
Java连接GCP Cloud SQL MySQL实例失败排查
本人出于学习研究目的,尝试将一个简易Java程序连接至Google Cloud Platform(GCP)上的MySQL数据库实例。目前该代码可正常连接本地localhost:3306端口运行的MySQL实例,但本地部署实例的实用性有限。
已验证可正常运行的场景
- Java客户端程序连接本地部署的MySQL数据库
- MySQL Workbench客户端连接本地部署的MySQL数据库
- MySQL Workbench客户端连接GCP平台部署的MySQL数据库
待实现目标
- 完成简易Java客户端程序与GCP平台部署的MySQL数据库的连通
环境信息
- 使用的依赖Jar包:
mysql-connector-java-8.0.29.jarmysql-socket-factory-1.6.1-jar-with-dependencies.jar
- 开发IDE:Eclipse
测试代码
package test; import java.sql.*; public class Test { public static void main(String[] args) { String CREDENTIALS = "jdbc:mysql://google/emexdb?cloudSqlInstance=ethereal-shine-354205:us-central1:emexdb-mysql&socketFactory=google.cloud.sql.mysql.SocketFactory&useSSL=false&user=****&password=***********"; try { // 建立数据库连接 Connection myConn = DriverManager.getConnection(CREDENTIALS); // 创建语句对象 Statement myStmt = myConn.createStatement(); // 执行SQL查询 ResultSet myRs = myStmt.executeQuery("select * from Test;"); // 处理结果集 while(myRs.next()) { System.out.println(myRs.getNString("id")+" "+myRs.getString("_name")); } myConn.close(); } catch(Exception eSQL) { eSQL.printStackTrace(); } } }
Eclipse运行抛出的错误信息
java.sql.SQLNonTransientConnectionException: Cannot connect to MySQL server on google:3,306. Make sure that there is a MySQL server running on the machine/port you are trying to connect to and that the machine this software is running on is able to connect to this host/port (i.e. not firewalled). Also make sure that the server has not been started with the --skip-networking flag. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73) at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:462) at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:683) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:253) at test.Test.main(Test.java:12) Caused by: java.lang.NullPointerException: Cannot invoke "com.mysql.cj.protocol.a.NativeProtocol.getSocketConnection()" because the return value of "com.mysql.cj.NativeSession.getProtocol()" is null at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:972) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:818) at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:448) ... 5 more
排查思路与解决方案
报错核心特征是JDBC驱动尝试直接连接主机名为google的3306端口,说明配置的Cloud SQL专用Socket Factory没有正常生效,按以下顺序排查即可:
- 第一步先检查Eclipse项目的依赖配置:右键项目 -> Build Path -> Configure Build Path,在Libraries页签确认两个Jar包都已正确加入构建路径。如果缺失,点击Add External JARs选择本地对应Jar包导入即可。这是该问题最高发的原因:Socket Factory类不在运行时类路径里,MySQL驱动不会识别URL里的Cloud SQL特殊参数,直接把
google当成普通数据库主机地址解析,才会抛出无法连接google:3306的错误,后续的空指针也是Socket Factory初始化失败触发的连锁异常。 - 确认依赖导入无误后,升级依赖版本:你用的
mysql-socket-factory-1.6.1版本发布时间过早,和mysql-connector-java-8.0.29存在已知兼容问题,将Socket Factory包升级到1.13.0及以上版本即可解决兼容类空指针问题。 - 检查网络连通权限:如果是本地公网环境连接GCP Cloud SQL,需要先把本机当前的公网IP添加到GCP Cloud SQL实例的授权网络列表中,否则连接会被GCP侧防火墙直接拦截。
- 校验连接URL参数:核对
cloudSqlInstance的取值和GCP控制台展示的实例连接名完全一致,格式为项目ID:实例所在区域:实例ID,不要写错区域或者实例名。如果你的Cloud SQL实例强制要求SSL连接,把URL里的useSSL=false改为useSSL=true,同时配置好对应的SSL证书或服务账号权限。 - 如果以上步骤都没解决,可以在JDBC连接URL末尾追加
&logger=com.mysql.cj.log.StandardLogger&profileSQL=true参数,开启驱动的详细运行日志,就能直接看到Socket Factory是否加载成功、连接流程具体卡在哪一步,快速定位剩余问题。
内容的提问来源于stack exchange,提问作者goldie4
相关产品推荐
相关产品推荐

