Google 云平台 - Spring 在云 SQL 上 MySQL 启动应用程序连接问题
Google Cloud Platform - Spring Boot application connection issues with MySQL on Cloud SQL
所以,我有一个最小的 Spring 引导应用程序,它应该连接到 GCP-Cloud SQL 上的 MySQL 数据库 SQL。
当我在本地 Google App Engine 上 运行 我的应用程序时,它设法连接到托管在 GCP 上的远程 MySQL 数据库。当我在 GAE 标准上部署完全相同的应用程序时,该应用程序(显然已在 GCP 上成功部署)无法连接到 MySQL 数据库。
这正是我的 application.properties 文件的样子:
查看 GCP 日志记录部分,我看到以下严重错误:
Uncaught exception from servlet\njava.lang.RuntimeException:
org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'userRepository' defined in com.winery.backend.services.UserRepository
defined in @EnableJpaRepositories declared onJpaRepositoriesRegistrar.
EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext'
while setting bean property 'mappingContext'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext':
等等几千行。 userRepository 恰好是我自定义的@Repository 注释接口。
同样,从本地到云,它就像一个魅力。
我看到有一些类似的线程,但其中 none 实际上提供了可行的解决方案。
可能是范围问题,如果两者(数据库和应用程序)都在同一主机中,可能无法通过 https 连接,因为无法解析主机。
两者是否在同一个 host/public IP 中?
如果您正在使用 docker:
- 尝试使用替代配置文件application-gcp.yml() 将public_ip 替换为docker 服务名称(并确保创建网络类型网桥)
如果你没有:
- 尝试使用 localhost 而不是 public IP
当您尝试使用云 SQL 的 public IP 地址进行连接时,您需要确定应用程序的 public IP 并将其 authorize连接到您的实例。这不适用于 App Engine,因为它不提供静态 IP 地址。
最好使用云 SQL 连接器并将此依赖项包含在 pom.xml 中:
<dependency>
<groupId>com.google.cloud.sql</groupId>
<artifactId>mysql-socket-factory-connector-j-8</artifactId>
<version>1.1.0</version>
</dependency>
然后创建一个JDBCURLlike this:
jdbc:mysql:///<DATABASE_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=<MYSQL_USER_NAME>&password=<MYSQL_USER_PASSWORD>
See the instance connection name on Cloud SQL in GCP console. The format should be "project-id:region:instance-name".
您还可以通过创建连接池来改进这一点:
private static final String CLOUD_SQL_CONNECTION_NAME = System.getenv("CLOUD_SQL_CONNECTION_NAME");
private static final String DB_USER = System.getenv("DB_USER");
private static final String DB_PASS = System.getenv("DB_PASS");
private static final String DB_NAME = System.getenv("DB_NAME");
private DataSource createConnectionPool() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(String.format("jdbc:mysql:///%s", DB_NAME));
config.setUsername(DB_USER); // e.g. "root", "postgres"
config.setPassword(DB_PASS); // e.g. "my-password"
config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
config.addDataSourceProperty("cloudSqlInstance", CLOUD_SQL_CONNECTION_NAME);
DataSource pool = new HikariDataSource(config);
return pool;
}
要查看完整上下文,see this guide。
所以,我有一个最小的 Spring 引导应用程序,它应该连接到 GCP-Cloud SQL 上的 MySQL 数据库 SQL。
当我在本地 Google App Engine 上 运行 我的应用程序时,它设法连接到托管在 GCP 上的远程 MySQL 数据库。当我在 GAE 标准上部署完全相同的应用程序时,该应用程序(显然已在 GCP 上成功部署)无法连接到 MySQL 数据库。
这正是我的 application.properties 文件的样子:
查看 GCP 日志记录部分,我看到以下严重错误:
Uncaught exception from servlet\njava.lang.RuntimeException:
org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'userRepository' defined in com.winery.backend.services.UserRepository
defined in @EnableJpaRepositories declared onJpaRepositoriesRegistrar.
EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext'
while setting bean property 'mappingContext'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext':
等等几千行。 userRepository 恰好是我自定义的@Repository 注释接口。 同样,从本地到云,它就像一个魅力。
我看到有一些类似的线程,但其中 none 实际上提供了可行的解决方案。
可能是范围问题,如果两者(数据库和应用程序)都在同一主机中,可能无法通过 https 连接,因为无法解析主机。
两者是否在同一个 host/public IP 中?
如果您正在使用 docker:
- 尝试使用替代配置文件application-gcp.yml() 将public_ip 替换为docker 服务名称(并确保创建网络类型网桥)
如果你没有:
- 尝试使用 localhost 而不是 public IP
当您尝试使用云 SQL 的 public IP 地址进行连接时,您需要确定应用程序的 public IP 并将其 authorize连接到您的实例。这不适用于 App Engine,因为它不提供静态 IP 地址。
最好使用云 SQL 连接器并将此依赖项包含在 pom.xml 中:
<dependency>
<groupId>com.google.cloud.sql</groupId>
<artifactId>mysql-socket-factory-connector-j-8</artifactId>
<version>1.1.0</version>
</dependency>
然后创建一个JDBCURLlike this:
jdbc:mysql:///<DATABASE_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=<MYSQL_USER_NAME>&password=<MYSQL_USER_PASSWORD>
See the instance connection name on Cloud SQL in GCP console. The format should be "project-id:region:instance-name".
您还可以通过创建连接池来改进这一点:
private static final String CLOUD_SQL_CONNECTION_NAME = System.getenv("CLOUD_SQL_CONNECTION_NAME");
private static final String DB_USER = System.getenv("DB_USER");
private static final String DB_PASS = System.getenv("DB_PASS");
private static final String DB_NAME = System.getenv("DB_NAME");
private DataSource createConnectionPool() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(String.format("jdbc:mysql:///%s", DB_NAME));
config.setUsername(DB_USER); // e.g. "root", "postgres"
config.setPassword(DB_PASS); // e.g. "my-password"
config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
config.addDataSourceProperty("cloudSqlInstance", CLOUD_SQL_CONNECTION_NAME);
DataSource pool = new HikariDataSource(config);
return pool;
}
要查看完整上下文,see this guide。