首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Spring 微服务技巧:使用环境变量抽象数据库主机名

  • 25-04-22 23:00
  • 2770
  • 8002
juejin.cn

为任何微服务安全地管理数据库连接字符串至关重要。通常,我们会使用环境变量来保护用户名和密码,却从未考虑过隐藏或掩码数据库主机名。在读写数据库实例中,有些组织会要求不得泄露主机名,并在应用程序启动时通过环境变量在运行时传递主机名。

本文讨论了如何在属性文件中通过环境变量配置主机名。

通过环境变量进行数据库配置

我们通常会以以下方式为 Spring 微服务配置默认连接字符串,数据库用户名和密码作为环境变量传递。

properties
代码解读
复制代码
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

如果我们的微服务连接到一个访问受限的安全数据库,并且数据库管理员或基础设施团队不希望你提供数据库主机名,那么我们就遇到了问题。通常,生产环境下数据库主机名可能如下所示:

properties
代码解读
复制代码
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 类

在这种情况下,管理员或云基础设施团队希望在容器启动时在运行时将主机名作为环境变量提供。其中一个选项是在配置类中构建并拼接连接字符串,如下所示:

java
代码解读
复制代码
@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); // 替换为你的实际用户名 dataSource.setPassword(dbUserPassword); // 替换为你的实际密码 return dataSource; } }

上述方法可以工作,但我更倾向于使用 application.properties 的方法,这种方法易于使用且相当灵活。属性文件允许你以集中方式整合所有配置,使其更易于更新和管理。它还通过将配置与代码分离来提高可读性。DevOps 团队可以在不更改代码的情况下更新环境变量的值。

通常,我们使用环境变量来设置数据库用户名和密码,并在 application.properties 文件中使用相应的表达式占位符 ${}。

properties
代码解读
复制代码
spring.esign.datasource.username=${DB_USER_NAME} spring.esign.datasource.password=${DB_USER_PASSWORD}

然而,对于数据库 URL,我们只需要在环境变量中使用主机名,而不是连接字符串,因为不同微服务的每个连接字符串都会有不同的参数。因此,为了解决这个问题,Spring 允许你在连接字符串中使用占位符表达式,如下所示;这提供了灵活性,并且能够继续使用 application.properties 文件的方法,而不是通过数据库配置类来实现。

properties
代码解读
复制代码
spring.esign.datasource.jdbc-url=jdbc:mysql://${ESIGN_DB_HOST}:3306/e-sign?allowPublicKeyRetrieval=true&useSSL=false

一旦我们决定了上述方法,并且如果出于某种原因需要在较低环境中排查问题,我们就可以使用 ApplicationListener 接口来查看解析后的 URL:

java
代码解读
复制代码
@Component public class ApplicationReadyLogger implements ApplicationListener { 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); } }

如果主机名配置存在问题,它将在应用程序启动时显示为错误。然而,在应用程序启动后,多亏了上述 ApplicationReadyLogger 实现,我们可以在应用程序日志中看到数据库 URL。请注意,我们不应在生产环境中这样做,因为基础设施团队希望对数据库写入主机名保密。

通过上述步骤,我们可以在 application.properties 文件的连接字符串中将数据库主机名配置为环境变量。

总结

使用环境变量为连接数据敏感数据库的主机名可以增强安全性和灵活性,并赋予云基础设施和 DevOps 团队更多权力。使用占位符表达式可以确保我们的配置保持清晰且易于维护。

注:本文转载自juejin.cn的蟹蟹蟹风流的文章"https://juejin.cn/post/7495948497126473754"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

103
后端
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top