安全地管理任何微服务的数据库连接字符串都至关重要;通常,我们使用环境变量来保护用户名和密码,并且从不考虑屏蔽或隐藏数据库主机名。在读取器和写入器数据库实例中,某些组织会强制要求在应用程序启动期间不要泄露主机名并通过环境变量传递主机名。本文讨论如何通过属性文件中的环境变量来配置主机名。
通过环境变量进行数据库配置
我们通常会按照以下方式为 Spring 微服务配置默认连接字符串,并将数据库用户名和密码作为环境变量传递。
server.port=8081 server.servlet.context-path=/api/e-sign/v1 spring.esign.datasource.jdbc-url=jdbc:mysql://localhost:3306/e-sign?allowPublicKeyRetrieval=true&useSSL=false spring.esign.datasource.username=${DB_USER_NAME} spring.esign.datasource.password=${DB_USER_PASSWORD} spring.esign.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.esign.datasource.minimumIdle=5 spring.esign.datasource.maxLifetime=120000
如果我们的微服务连接到具有有限访问权限的安全数据库,并且数据库管理员或基础结构团队不希望你提供数据库主机名,那么我们就有问题了。通常,生产数据库主机名如下所示:
spring.esign.datasource.jdbc-url=jdbc:mysql://prod-db.fabrikam.com:3306/e-sign?allowPublicKeyRetrieval=true&useSSL=false spring.esign.datasource.username=${DB_USER_NAME} spring.esign.datasource.password=${DB_USER_PASSWORD}
使用 @Configuration 类
在这种情况下,管理员或云基础架构团队希望他们在容器启动时在运行时将主机名作为环境变量提供。其中一个选项是在配置类中构建和连接连接字符串,如下所示:
@Configuration public class DatabaseConfig { private final Environment environment; public DatabaseConfig(Environment environment) { this.environment = environment; } @Bean public DataSource databaseDataSource() { String hostForDatabase = environment.getProperty("ESIGN_DB_HOST", "localhost:3306"); String dbUserName = environment.getProperty("DB_USER_NAME", "user-name"); String dbUserPassword = environment.getProperty("DB_USER_PASSWORD", "user-password"); String url = String.format("jdbc:mysql://%s/e-sign?allowPublicKeyRetrieval=true&useSSL=false", hostForDatabase); DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl(url); dataSource.setUsername(dbUserName); // Replace with your actual username dataSource.setPassword(dbUserPassword); // Replace with your actual password return dataSource; } }
上述方法可行,但我们需要将该方法与 一起使用,该方法易于使用且非常灵活。属性文件允许您以集中方式整理所有配置,从而更易于更新和管理。它还通过将配置与代码分离来提高可读性。DevOps 团队可以在不更改代码的情况下更新环境变量值。application.properties
数据库主机名的环境变量
通常,我们使用环境变量来表示数据库用户名和密码,并在应用程序属性文件中使用相应的表达式占位符表达式。${}
spring.esign.datasource.username=${DB_USER_NAME} spring.esign.datasource.password=${DB_USER_PASSWORD}
但是,对于数据库 URL,我们只需要将环境变量用于主机名,而不需要用于连接字符串,因为不同微服务的每个连接字符串都具有不同的参数。因此,为了解决这个问题,Spring 允许您在下面显示的连接字符串中使用占位符表达式;这提供了灵活性和坚持使用文件的方法的能力,而不是通过数据库配置类来执行。application.properties
spring.esign.datasource.jdbc-url=jdbc:mysql://${ESIGN_DB_HOST}:3306/e-sign?allowPublicKeyRetrieval=true&useSSL=false
一旦我们决定了上述方法,并且如果我们需要在较低的环境中出于任何原因解决任何问题,我们就可以使用界面来查看已解决的 URL:ApplicationListener
爪哇岛
@Component public class ApplicationReadyLogger implements ApplicationListener<ApplicationReadyEvent> { private final Environment environment; public ApplicationReadyLogger(Environment environment) { this.environment = environment; } @Override public void onApplicationEvent(ApplicationReadyEvent event) { String jdbcUrl = environment.getProperty("spring.esign.datasource.jdbc-url"); System.out.println("Resolved JDBC URL: " + jdbcUrl); } }
如果主机名配置有问题,它将在应用程序启动时显示为错误。但是,在应用程序启动后,由于上述实现,我们可以在应用程序日志中看到数据库 URL。请注意,在基础设施团队希望对数据库编写器主机名保持保密的生产环境中,我们不应这样做。ApplicationReadyLogger
使用上述步骤,我们可以将数据库主机名配置为文件内部连接字符串中的环境变量。application.properties
使用数据库主机名的环境变量连接到数据敏感数据库可以增强安全性和灵活性,并为云基础架构和 DevOps 团队提供更多功能。使用占位符表达式可确保我们的配置保持清晰且可维护。