You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

连接Cloud SQL实例时出现NoClassDefFoundError及连接超时问题求助

连接Cloud SQL实例时遇到初始化失败及连接超时问题

问题描述

尝试将服务连接至Cloud SQL实例时,触发java.lang.NoClassDefFoundError: Could not initialize class com.blacklight.common.DBManager错误,底层报错为连接超时导致的通信链路故障。

DBManager类代码

package com.blacklight.common;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

@WebListener("Initialize db upon initialization of application context")
public class DBManager implements ServletContextListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(DBManager.class);

    private static final Object dataSourceLock = new Object();
    private static DataSource dataSource = null;

    static {
        dataSource = initDataSource();
    }

    private static DataSource initDataSource() {
        synchronized (dataSourceLock) {
            try  {
                String username = "aaaa";
                String password = "bbbb";

                String driverName = "com.mysql.jdbc.Driver";
                String instance = "project-Id:location:database-name";


                if (dataSource == null) {

                    HikariConfig config = new HikariConfig();
                    config.setUsername(username);
                    config.setPassword(password);

                    config.setJdbcUrl("jdbc:mysql:///Features");
                    config.setUsername(username);
                    config.setPassword(password);

                    config.setDriverClassName(driverName);
                    config.setConnectionInitSql("SET NAMES 'utf8mb4'");
                    config.addDataSourceProperty("socketFactory","com.google.cloud.sql.mysql.SocketFactory");
                    config.addDataSourceProperty("cloudSqlInstance", instance);
                    config.addDataSourceProperty("characterEncoding", "UTF-8");
                    config.addDataSourceProperty("useUnicode", "true");
//                    config.addDataSourceProperty("noAccessToProcedureBodies", "true");

                    config.addDataSourceProperty("useSSL", "true");
                    config.addDataSourceProperty("ipTypes", "PRIVATE,PUBLIC");

                    config.setMaximumPoolSize(50);
                    config.setMinimumIdle(5);
                    config.setConnectionTimeout(10000);
                    config.setIdleTimeout(600000);
                    config.setMaxLifetime(1800000);

                    dataSource = new HikariDataSource(config);
                }
                return dataSource;
            } catch (Exception e) {
                System.out.println("Error");
                LOGGER.error(e.getMessage(), e);
            }
            throw new RuntimeException("Couldn't initialize datasource");
        }
    }

    public static Connection getConnection() throws SQLException {
        if (dataSource == null) {
            dataSource = initDataSource();
        }
        return dataSource.getConnection();
    }

    @Override
    public void contextInitialized(ServletContextEvent event) {
        dataSource = initDataSource();
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        if (dataSource != null) {
            ((HikariDataSource) dataSource).close();
        }
    }

}

错误日志(中文翻译)

com.blacklight.common.DBManager initDataSource: 初始化连接池失败:通信链路故障
最后一次成功向服务器发送数据包是在0毫秒前,驱动未收到来自服务器的任何数据包。
com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: 初始化连接池失败:通信链路故障
最后一次成功向服务器发送数据包是在0毫秒前,驱动未收到来自服务器的任何数据包。
    at com.zaxxer.hikari.pool.HikariPool.throwPoolInitializationException(HikariPool.java:596)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:582)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
    at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:81)
    at com.blacklight.common.DBManager.initDataSource(DBManager.java:71)
    at com.blacklight.common.DBManager.<init>(DBManager.java:26)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.eclipse.jetty.server.handler.ContextHandler$StaticContext.createInstance(ContextHandler.java:2902)
    at org.eclipse.jetty.servlet.ServletContextHandler$Context.createInstance(ServletContextHandler.java:1299)
    at org.eclipse.jetty.server.handler.ContextHandler$StaticContext.createListener(ContextHandler.java:2913)
    at org.eclipse.jetty.servlet.ListenerHolder.doStart(ListenerHolder.java:94)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:369)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1449)
    at com.google.apphosting.runtime.jetty94.AppEngineWebAppContext.startWebapp(AppEngineWebAppContext.java:274)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1414)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:916)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:288)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:524)
    at com.google.apphosting.runtime.jetty94.AppEngineWebAppContext.doStart(AppEngineWebAppContext.java:218)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at com.google.apphosting.runtime.jetty94.AppVersionHandlerFactory.doCreateHandler(AppVersionHandlerFactory.java:207)
    at com.google.apphosting.runtime.jetty94.AppVersionHandlerFactory.createHandler(AppVersionHandlerFactory.java:125)
    at com.google.apphosting.runtime.jetty94.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:82)
    at com.google.apphosting.runtime.jetty94.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:176)
    at com.google.apphosting.runtime.RequestRunner.dispatchServletRequest(RequestRunner.java:264)
    at com.google.apphosting.runtime.RequestRunner.dispatchRequest(RequestRunner.java:229)
    at com.google.apphosting.runtime.RequestRunner.run(RequestRunner.java:194)
    at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:273)
    at java.lang.Thread.run(Thread.java:750)
原因:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 通信链路故障
最后一次成功向服务器发送数据包是在0毫秒前,驱动未收到来自服务器的任何数据包。
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1117)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:350)
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2416)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2450)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2235)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:818)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:404)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:307)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
    ... 31 more
根本原因:java.net.ConnectException: 连接超时(连接超时)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:607)
    at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:293)
    at sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:173)
    at com.google.cloud.sql.core.CoreSocketFactory.createSslSocket(CoreSocketFactory.java:275)
    at com.google.cloud.sql.core.CoreSocketFactory.connect(CoreSocketFactory.java:229)
    at com.google.cloud.sql.core.CoreSocketFactory.connect(CoreSocketFactory.java:188)
    at com.google.cloud.sql.mysql.SocketFactory.connect(SocketFactory.java:41)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:300)

排查与解决步骤

  • 校验Cloud SQL实例配置与权限

    • 确认cloudSqlInstance参数值为正确格式:项目ID:区域:实例名,替换代码中的占位符为实际信息
    • 确保应用运行环境的服务账号拥有Cloud SQL Client角色权限,可在IAM控制台配置
    • 若应用部署在非App Engine环境,需将应用所在IP加入Cloud SQL实例的授权网络列表
  • 检查依赖包兼容性

    • 确认已引入com.google.cloud.sql:mysql-socket-factory依赖,版本需与MySQL驱动、Cloud SDK适配
    • 替换旧版MySQL驱动:将com.mysql.jdbc.Driver改为com.mysql.cj.jdbc.Driver(适配MySQL 8.0+),同时升级驱动版本至兼容Socket Factory的版本
  • 优化代码初始化逻辑

    • 删除静态代码块中的数据源初始化:类加载阶段执行初始化易受上下文未就绪影响,仅保留contextInitialized方法内的初始化逻辑
    • 移除重复的config.setUsername和config.setPassword调用,避免冗余配置
    • 调整连接池参数:将maximumPoolSize从50下调至10-20,匹配实际并发需求,减少资源占用
  • 调整连接配置

    • 若使用MySQL 8.0+,设置useSSL=false(Cloud SQL Socket Factory已处理加密连接),或添加requireSSL=true
    • 移除ipTypes=PRIVATE,PUBLIC配置,默认Socket Factory会自动选择最优连接路径

内容的提问来源于stack exchange,提问作者Sahil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:20:53