我正在努力过渡到 Google Cloud MySQL。我们目前已连接到我们自己的托管 mysql 服务器,并且工作正常。我们使用四个独立的 MySql 连接,因此设置并不简单。这是我专门针对 Google Cloud MySQL 所做的更改
pom.xml:
<dependencies>
....
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud.sql</groupId>
<artifactId>mysql-socket-factory-connector-j-8</artifactId>
</dependency>
.....
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>5.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
应用程序属性:
spring.cloud.gcp.project-id=PROJECT_ID
spring.cloud.gcp.credentials.location=classpath:CREDENTIAL_FILE_LOCATION
spring.cloud.gcp.sql.enabled=false
userdb.read.datasource.url=jdbc:mysql:///DB_NAME?cloudSqlInstance=INSTANCE_NAME&socketFactory=com.google.cloud.sql.mysql.SocketFactory
userdb.read.datasource.username=USERNAME
userdb.read.datasource.password=PASSWORD
userdb.read.datasource.tomcat.max-wait=5000
userdb.read.datasource.tomcat.max-active=2
userdb.read.datasource.tomcat.test-on-borrow=true
# THREE MORE SIMILAR CONNECTION SETTINGS
除了连接设置之外,我还配置了凭据。我的其余代码按原样,您认为我做错了什么?以下是我收到的错误:
: HikariPool-1 - Exception during pool initialization.
java.sql.SQLNonTransientConnectionException: Could not create connection to database server.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:111) ~[mysql-connector-j-8.1.0.jar:8.1.0]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:98) ~[mysql-connector-j-8.1.0.jar:8.1.0]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:90) ~[mysql-connector-j-8.1.0.jar:8.1.0]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:64) ~[mysql-connector-j-8.1.0.jar:8.1.0]
at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:995) ~[mysql-connector-j-8.1.0.jar:8.1.0]
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:809) ~[mysql-connector-j-8.1.0.jar:8.1.0]
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:440) ~[mysql-connector-j-8.1.0.jar:8.1.0]
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:239) ~[mysql-connector-j-8.1.0.jar:8.1.0]
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:188) ~[mysql-connector-j-8.1.0.jar:8.1.0
Caused by: java.lang.RuntimeException: Unable to obtain credentials to communicate with the Cloud SQL API
at com.google.cloud.sql.core.ApplicationDefaultCredentialFactory.getCredentials(ApplicationDefaultCredentialFactory.java:42) ~[jdbc-socket-factory-core-1.14.1.jar:1.14.1]
at com.google.cloud.sql.core.ApplicationDefaultCredentialFactory.create(ApplicationDefaultCredentialFactory.java:32) ~[jdbc-socket-factory-core-1.14.1.jar:1.14.1]
at com.google.cloud.sql.core.CoreSocketFactory.apiFetcher(CoreSocketFactory.java:417) ~[jdbc-socket-factory-core-1.14.1.jar:1.14.1]
at com.google.cloud.sql.core.CoreSocketFactory.lambda$getCloudSqlInstance$0(CoreSocketFactory.java:396) ~[jdbc-socket-factory-core-1.14.1.jar:1.14.1]
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[?:?]
Caused by: java.io.IOException: Your default credentials were not found. To set up Application Default Credentials for your environment, see https://cloud.google.com/docs/authentication/external/set-up-adc.
at com.google.auth.oauth2.DefaultCredentialsProvider.getDefaultCredentials(DefaultCredentialsProvider.java:127) ~[google-auth-library-oauth2-http-1.20.0.jar:1.20.0]
at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:129) ~[google-auth-library-oauth2-http-1.20.0.jar:1.20.0]
at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:101) ~[google-auth-library-oauth2-http-1.20.0.jar:1.20.0]
at com.google.cloud.sql.core.ApplicationDefaultCredentialFactory.getCredentials(ApplicationDefaultCredentialFactory.java:40) ~[jdbc-socket-factory-core-1.14.1.jar:1.14.1]
at com.google.cloud.sql.core.ApplicationDefaultCredentialFactory.create(ApplicationDefaultCredentialFactory.java:32) ~[jdbc-socket-factory-core-1.14.1.jar:1.14.1]
at com.google.cloud.sql.core.CoreSocketFactory.apiFetcher(CoreSocketFactory.java:417) ~[jdbc-socket-factory-core-1.14.1.jar:1.14.1]
at com.google.cloud.sql.core.CoreSocketFactory.lambda$getCloudSqlInstance$0(CoreSocketFactory.java:396) ~[jdbc-socket-factory-core-1.14.1.jar:1.14.1]
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[?:?]
在我看来,您正在尝试使用 Cloud SQL Java 连接器 (cloud-sql-jdbc-socket-factory) 连接到 SQL 实例。 Java 连接器调用 GoogleCredentials.getApplicationDefault() 来获取 Google 凭据。根据 API 文档,该 API 按此顺序搜索凭证文件,
- GOOGLE_APPLICATION_CREDENTIALS 环境变量指向的凭据文件
- Google Cloud SDK 提供的凭据。
- gcloud auth 应用程序 - 用户帐户凭据的默认登录。
- gcloud auth application-default login --impersonate-service-account 用于模拟服务帐户凭据。
- Google App Engine 内置凭据
- Google Cloud Shell 内置凭据
- Google 计算引擎内置凭据
其中似乎不包括Spring boot的application.properties。也许您可以尝试使用上述方法之一?
花了很多时间后,发现解决方案非常简单。在这里添加它以防有人遇到类似的问题。我使用
spring.cloud.gcp.credentials.location
属性来设置凭据,但 google cloud sql 连接工厂库 并不关心这一点。我们需要使用 gcloud auth application-default login
命令来创建凭证,gcloud 命令将其保存在您的文件夹中: /Users/your_user_name/.config/gcloud/application_default_credentials.json 。 Spring Boot 应用程序会自动选择它,无需使用 spring.cloud.gcp.credentials.location 文件进行设置。