【问题标题】:Cannot connect Spring Boot with Cloud SQL using spring cloud gcp starter无法使用 spring cloud gcp starter 将 Spring Boot 与 Cloud SQL 连接
【发布时间】:2018-12-15 21:44:56
【问题描述】:

Spring Boot 新手试图将我的应用托管在 GCP AppEngine Flexible with Cloud SQL (mysql),第二代。

使用我从这里获得的 Spring Cloud GCP 启动器: https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-sql-sample,我正在尝试让我的本地 Spring Boot 应用程序连接到 Cloud SQL。尝试在本地 Tomcat 上运行 SQLApplication 时,我得到:

2018-07-28 20:57:35.663  INFO 66641 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2018-07-28 20:57:36.730 ERROR 66641 --- [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Exception during pool initialization.

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create socket factory 'com.google.cloud.sql.mysql.SocketFactory' due to underlying exception: 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_171]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_171]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_171]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_171]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.Util.getInstance(Util.java:386) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.MysqlIO.createSocketFactory(MysqlIO.java:3411) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:303) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2482) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2519) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2304) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:834) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_171]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_171]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_171]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_171]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:416) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:346) ~[mysql-connector-java-5.1.26-bin.jar:na]
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:117) ~[HikariCP-2.7.9.jar:na]
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:123) ~[HikariCP-2.7.9.jar:na]
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:365) ~[HikariCP-2.7.9.jar:na]
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:194) ~[HikariCP-2.7.9.jar:na]
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:460) [HikariCP-2.7.9.jar:na]
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:534) [HikariCP-2.7.9.jar:na]
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) [HikariCP-2.7.9.jar:na]
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) [HikariCP-2.7.9.jar:na]
    at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:151) [spring-jdbc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115) [spring-jdbc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78) [spring-jdbc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:46) [spring-jdbc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runScripts(DataSourceInitializer.java:210) [spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.createSchema(DataSourceInitializer.java:104) [spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker.afterPropertiesSet(DataSourceInitializerInvoker.java:64) [spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1767) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1704) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:581) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:224) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1015) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:339) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:334) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor.postProcessAfterInitialization(DataSourceInitializerPostProcessor.java:55) ~[spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:439) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1712) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:581) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:818) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:724) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:197) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1276) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1133) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1256) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1105) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:818) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:724) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:197) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1276) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1133) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at com.example.SqlApplication.main(SqlApplication.java:29) ~[classes/:na]
Caused by: java.lang.ClassNotFoundException: com.google.cloud.sql.mysql.SocketFactory
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_171]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_171]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_171]
    at java.lang.Class.forName0(Native Method) ~[na:1.8.0_171]
    at java.lang.Class.forName(Class.java:264) ~[na:1.8.0_171]
    at com.mysql.jdbc.MysqlIO.createSocketFactory(MysqlIO.java:3408) ~[mysql-connector-java-5.1.26-bin.jar:na]
    ... 95 common frames omitted

我对这个项目所做的唯一更改是 application.properties。我也使用 gcloud 进行了身份验证。

这是我的 application.properties,不起作用:

spring.cloud.gcp.sql.database-name=sqldemo
spring.cloud.gcp.sql.instance-connection-name=Project:Region:Instance
spring.datasource.continue-on-error=true
spring.datasource.initialization-mode=always
spring.datasource.username=myuser
spring.datasource.password=mypass

我试过直接在pom.xml中添加mysql socket factory,但是没有成功:

<dependency>
    <groupId>com.google.cloud.sql</groupId>
    <artifactId>mysql-socket-factory</artifactId>
    <version>1.0.10</version>
</dependency>

我已确保我的 SQL API 已启用。 谢谢!

【问题讨论】:

  • 如果您尝试运行此命令会怎样。 $ mvn clean jetty:run -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root -Dpassword=myPassword -Ddatabase=myDatabase 我知道您已经尝试在没有 - 之后的部分的情况下运行它。
  • 请始终将项目 ID 写为 [MY_PROJECT_ID]。这是敏感的私人数据
  • 另外请分享您的pom.xml
  • 我从云计算实例运行它,我没有任何错误。您能否提供完整的跟踪信息以便我们了解更多上下文?

标签: google-app-engine spring-boot google-cloud-platform google-cloud-sql


【解决方案1】:

我在启动 spring-cloud-gcp-sql-sample 时也遇到了问题,我设法使用以下 pom.xml 运行它:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <parent>
        <artifactId>spring-cloud-gcp-samples</artifactId>
        <groupId>org.springframework.cloud</groupId>
        <version>1.1.0.BUILD-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-cloud-gcp-sql-sample</artifactId>
    <name>Spring Cloud GCP SQL MySQL Starter Code Sample</name>
  <packaging>jar</packaging>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

    <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

  <repositories>
    <!-- Use Spring Milestone Repository -->
    <repository>
      <id>repository.spring.milestone</id>
      <name>Spring Milestones Repository</name>
      <url>http://repo.spring.io/milestone</url>
    </repository>
  </repositories>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-gcp-dependencies</artifactId>
        <version>1.0.0.RC1</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>1.5.7.RELEASE</version>
        <executions>
          <execution>
            <goals>
              <goal>repackage</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

    </plugins>
  </build>

</project>

和application.properties:

spring.cloud.gcp.sql.instance-connection-name=[your-server-name]
spring.cloud.gcp.sql.database-name=[your-database-name]

# So app starts despite "table already exists" errors.
spring.datasource.continue-on-error=true

# Enforces database initialization
spring.datasource.initialization-mode=always

# Leave empty for root, uncomment and fill out if you specified a user
spring.datasource.username=root

## Uncomment if root password is specified
spring.datasource.password=root

server.port = 80

我已使用 gcloud 进行了身份验证。 我正在使用 spring-boot:run 运行此示例

【讨论】:

    【解决方案2】:

    在配置spring之前,必须启用cloud sql admin api

    在具有角色的凭据中创建 json:

    Cloud SQL > Cloud SQL Client
    Cloud SQL > Cloud SQL Editor
    Cloud SQL > Cloud SQL Admin
    
    kubectl create secret generic cloudsql-instance-credentials --from-file=credentials.json=file_name.json
    
    kubectl create secret generic cloudsql-db-credentials --from-literal=username=ethan --from-literal=password=12345678 --from-literal=dbname=clash_royale --from-literal=connectname=projectid:region:instance-name
    

    双向连接gcloud sql,完美运行

    1. 云 SQL 代理

    配置文件deployment.yaml

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: {{ template "fullname" . }}
      labels:
        draft: {{ default "draft-app" .Values.draft }}
        chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
    spec:
      replicas: {{ .Values.replicaCount }}
      template:
        metadata:
          labels:
            draft: {{ default "draft-app" .Values.draft }}
            app: {{ template "fullname" . }}
    {{- if .Values.podAnnotations }}
          annotations:
    {{ toYaml .Values.podAnnotations | indent 8 }}
    {{- end }}
        spec:
          containers:
          - name: {{ .Chart.Name }}
            image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
            imagePullPolicy: {{ .Values.image.pullPolicy }}
            env:
              - name: DB_HOST
                value: 127.0.0.1:3306
              # These secrets are required to start the pod.
              # [START cloudsql_secrets]
              - name: DB_USER
                valueFrom:
                  secretKeyRef:
                    name: cloudsql-db-credentials
                    key: username
              - name: DB_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: cloudsql-db-credentials
                    key: password
              # [END cloudsql_secrets]
          # Change <INSTANCE_CONNECTION_NAME> here to include your GCP
          # project, the region of your Cloud SQL instance and the name
          # of your Cloud SQL instance. The format is
          # $PROJECT:$REGION:$INSTANCE
          # [START proxy_container]
          - name: cloudsql-proxy
            image: gcr.io/cloudsql-docker/gce-proxy:1.11
            command: ["/cloud_sql_proxy",
                      "-instances=PROJECT:REGION:INSTANCE=tcp:3306",
                      "-credential_file=/secrets/cloudsql/credentials.json"]
            # [START cloudsql_security_context]
            securityContext:
              runAsUser: 2  # non-root user
              allowPrivilegeEscalation: false
            # [END cloudsql_security_context]
            volumeMounts:
              - name: cloudsql-instance-credentials
                mountPath: /secrets/cloudsql
                readOnly: true
          # [END proxy_container]
            ports:
            - containerPort: {{ .Values.service.internalPort }}
            livenessProbe:
              httpGet:
                path: {{ .Values.probePath }}
                port: {{ .Values.service.internalPort }}
              initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
              periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
              successThreshold: {{ .Values.livenessProbe.successThreshold }}
              timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
            readinessProbe:
              httpGet:
                path: {{ .Values.probePath }}
                port: {{ .Values.service.internalPort }}
              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
              successThreshold: {{ .Values.readinessProbe.successThreshold }}
              timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
            resources:
    {{ toYaml .Values.resources | indent 12 }}
          terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
          serviceAccountName: {{ .Values.service.name }}
          # [START volumes]
          volumes:
            - name: cloudsql-instance-credentials
              secret:
                secretName: cloudsql-instance-credentials
          # [END volumes]

    pom.xml

        <!-- DATABASE-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>

    application.properties

    #database=mysql
    spring.datasource.driverClassName=com.mysql.jdbc.Driver
    spring.datasource.url = jdbc:mysql://${DB_HOST}/{$DB_NAME}?useSSL=false
    spring.datasource.username=${DB_USER}
    spring.datasource.password=${DB_PASSWORD}
    
    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
    spring.jpa.hibernate.ddl-auto = update
    1. 没有代理

    deployment.yaml

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: {{ template "fullname" . }}
      labels:
        draft: {{ default "draft-app" .Values.draft }}
        chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
    spec:
      replicas: {{ .Values.replicaCount }}
      template:
        metadata:
          labels:
            draft: {{ default "draft-app" .Values.draft }}
            app: {{ template "fullname" . }}
    {{- if .Values.podAnnotations }}
          annotations:
    {{ toYaml .Values.podAnnotations | indent 8 }}
    {{- end }}
        spec:
          containers:
          - name: {{ .Chart.Name }}
            image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
            imagePullPolicy: {{ .Values.image.pullPolicy }}
            volumeMounts:
              - name: cloudsql-instance-credentials
                mountPath: /secrets/cloudsql
                readOnly: true
            env:
              - name: DB_HOST
                value: 127.0.0.1:3306
              # These secrets are required to start the pod.
              # [START cloudsql_secrets]
              - name: DB_USER
                valueFrom:
                  secretKeyRef:
                    name: cloudsql-db-credentials
                    key: username
              - name: DB_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: cloudsql-db-credentials
                    key: password
              - name: DB_NAME
                valueFrom:
                  secretKeyRef:
                    name: cloudsql-db-credentials
                    key: dbname
              - name: CONNECT_NAME
                valueFrom:
                  secretKeyRef:
                    name: cloudsql-db-credentials
                    key: connectname
              # [END cloudsql_secrets]
          # Change <INSTANCE_CONNECTION_NAME> here to include your GCP
          # project, the region of your Cloud SQL instance and the name
          # of your Cloud SQL instance. The format is
          # $PROJECT:$REGION:$INSTANCE
          # [START proxy_container]
    #      - name: cloudsql-proxy
    #        image: gcr.io/cloudsql-docker/gce-proxy:1.11
    #        command: ["/cloud_sql_proxy",
    #                  "-instances=",
    #                  "-credential_file=/secrets/cloudsql/credentials.json"]
    #        # [START cloudsql_security_context]
    #        securityContext:
    #          runAsUser: 2  # non-root user
    #          allowPrivilegeEscalation: false
    #        # [END cloudsql_security_context]
    #        volumeMounts:
    #          - name: cloudsql-instance-credentials
    #            mountPath: /secrets/cloudsql
    #            readOnly: true
          # [END proxy_container]
            ports:
            - containerPort: {{ .Values.service.internalPort }}
            livenessProbe:
              httpGet:
                path: {{ .Values.probePath }}
                port: {{ .Values.service.internalPort }}
              initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
              periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
              successThreshold: {{ .Values.livenessProbe.successThreshold }}
              timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
            readinessProbe:
              httpGet:
                path: {{ .Values.probePath }}
                port: {{ .Values.service.internalPort }}
              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
              successThreshold: {{ .Values.readinessProbe.successThreshold }}
              timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
            resources:
    {{ toYaml .Values.resources | indent 12 }}
          terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
          serviceAccountName: {{ .Values.service.name }}
          # [START volumes]
          volumes:
            - name: cloudsql-instance-credentials
              secret:
                secretName: cloudsql-instance-credentials
          # [END volumes]

    pom.xml

    		<!-- DATABASE-->
    
    		<!--<dependency>-->
    			<!--<groupId>mysql</groupId>-->
    			<!--<artifactId>mysql-connector-java</artifactId>-->
    		<!--</dependency>-->
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-jpa</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
    			<version>1.0.0.RELEASE</version>
    		</dependency>

    application.properties

    spring.cloud.gcp.sql.instance-connection-name=${CONNECT_NAME}
    spring.cloud.gcp.sql.database-name=${DB_NAME}
    spring.datasource.username=${DB_USER}
    spring.datasource.password=${DB_PASSWORD}
    spring.cloud.gcp.credentials.location=file:/secrets/cloudsql/credentials.json
    
    # So app starts despite "table already exists" errors.
    spring.datasource.continue-on-error=true
    
    # Enforces database initialization
    spring.datasource.initialization-mode=always
    
    spring.jpa.database-platform=org.hibernate.dialect.MySQL55Dialect

    希望对你有帮助。

    【讨论】:

    • 你把你的 secrets.yml 放在资源下面了吗?和 deployment.yml 一样吗?
    • 是的,我把它放在了secret.yaml中
    • @EthanNguyen 感谢您的描述。我按照您的示例(使用代理)但收到错误Warning FailedMount 14s (x7 over 45s) kubelet, gke-gara-cluster-default-pool-673744a2-n377 MountVolume.SetUp failed for volume "cloudsql-instance-credentials" : secrets "cloudsql-instance-credentials" not found。我刚刚创建了 cloudsql-db-credentials。我还必须为卷创建具有相同凭据的文件?
    【解决方案3】:

    我认为你应该设置一个代理

    https://cloud.google.com/sql/docs/mysql/sql-proxy

    【讨论】:

      【解决方案4】:

      您无需设置 Cloud SQL 代理。 正如您在documentation 中看到的那样:

      请注意,您无需使用代理或配置 SSL 即可从 App Engine 标准或柔性环境连接到 Cloud SQL。这些连接自动使用“内置”代理实现。

      使用 App Engine Java,Cloud SQL Socket Factory 在幕后建立 jdbc 连接,无需任何 IP 地址,只需实例名称。

      似乎找不到此库或创建新实例时出现问题。

      请检查this gist 与 pom.xml 和 application.properties。

      【讨论】:

        猜你喜欢
        • 2020-06-03
        • 2020-06-26
        • 2020-08-31
        • 2021-05-07
        • 1970-01-01
        • 1970-01-01
        • 2021-04-02
        • 2018-07-22
        • 2018-10-03
        相关资源
        最近更新 更多