首页 > 解决方案 > 以编程方式在本地数据库和 Google Cloud SQL 之间切换

问题描述

我正在使用 Spring Boot 中的一个项目,直到现在只使用本地 Postgres 数据库。但是,我们现在正在努力将应用程序部署到涉及使用 Cloud SQL 的 Google 云平台。我找到了一些关于如何连接到 Cloud SQL 的指南,并决定遵循这个

但是,我们无法在 Cloud SQL 中运行单独的开发数据库,​​因此希望继续使用本地 Postgres 数据库进行开发。为此,我编写了以下代码:

@Configuration
@EnableTransactionManagement
public class PersistenceContext {
    @Bean
    public DriverManagerDataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl(System.getenv("DB_URL"));
        dataSource.setUsername(System.getenv("DB_USER"));
        dataSource.setPassword(System.getenv("DB_PASS"));

        String dbInstance = System.getenv("DB_INSTANCE");

        if (dbInstance != null && !dbInstance.isEmpty()) {
            Properties connectionProperties = new Properties();
            connectionProperties
                .setProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory");
            connectionProperties.setProperty("cloudSqlInstance", dbInstance);

            dataSource.setConnectionProperties(connectionProperties);
        }

        return dataSource;
    }
}

有了这个,我希望简单地不指定云 SQL 套接字工厂和 dbInstance 将允许我使用本地数据库。但是,当尝试仅使用 DB url、用户和密码变量集运行应用程序时,我遇到了以下异常:

java.lang.IllegalArgumentException:实例连接名称必须以 格式提供<PROJECT_ID>:<REGION>:<INSTANCE_ID>

完整的堆栈跟踪可以在这里找到

DB URL 配置如下:

DB_URLjdbc:postgresql://localhost:5432/soundshare

如何以编程方式在数据库之间切换?(如果可以避免,我宁愿不将数据库详细信息存储在配置文件中)

谢谢!

标签: javapostgresqlspring-bootgoogle-cloud-platformgoogle-cloud-sql

解决方案


因此,正如@Thomas Andolf 提到的那样,在代码中自己做并不是一个好主意,基本上是在重新发明轮子。有几种方法可以“外部化”您的配置。

https://docs.spring.io/spring-boot/docs/1.2.2.RELEASE/reference/html/boot-features-external-config.html

就我个人而言,我喜欢尽可能使用 os 环境变量,因为当我部署为容器时,我也可以轻松地进行交换。

这是我正在处理的项目的 application.properties 文件的横截面:

spring.datasource.url=${ospec_db_url} spring.datasource.username=${ospec_db_user:somedefault} spring.datasource.password=${ospec_db_password}

在我的开发系统上,我只设置了环境变量,它就会被拾取。就我而言,我有一个包含如下变量的文本文件:

导出 ospec_db_url=jdbc:postgresql://localhost:5432/ospec_db
导出 ospec_db_password=somebadasspassword

我只是获取文本文件并应用它。我可以轻松地在这样做的项目之间切换。当你为 K8s 打包时,你可以从秘密文件中读取到你的环境变量,当你去云时,你可以将值作为变量传递到你的启动脚本中。


推荐阅读