Spring Cloud Config 使用 GIT 以外的配置源
1、简介
Spring Cloud Config 是 Spring Cloud 生态下的一个子项目,可让 Spring 应用轻松实现配置外部化。通过它,可以将配置数据作为服务暴露出来,从而使得任何具有 HTTP 客户端的应用都可以轻松地获取配置数据。
本文将会带你了解如何在 Spring Cloud Config 中使用 Git 以外的配置源来存储配置信息。
2、Spring Cloud Config 概览
Spring Cloud Config 采用了典型的客户端-服务器模型。集中式服务器(或多个服务器)从外部数据源读取配置数据。这些服务器会暴露各种 HTTP 端点,允许任何其他应用查询配置数据。
Spring Cloud Config 还能让 Spring Boot 应用非常方便地自动连接到配置服务器。服务器提供的配置数据可以像客户端应用中的其他属性源一样使用。
3、GIT
Spring Cloud Config 最常见的使用案例是在 git 仓库中存储配置数据。这种方式的设置有几个优点:
- 灵活性:git 仓库可以容纳各种类型的文件,包括二进制文件。
- 安全性:可轻松控制细粒度的读写权限。
- 审计:强大的历史跟踪功能可轻松审核配置更改。
- 标准化:无论哪家提供商(Provider),Git 操作都是标准的,这意味着我们可以自行托管或使用任意数量的第三方提供商。
- 分布式: Git 从一开始就是为分布式设计的,因此非常适合云原生和微服务架构。
尽管有上述种种好处,但 git 并不总是存储配置数据的最佳选择。例如,项目可能已经将配置数据放在其他数据存储(如关系型数据库)中。在这种情况下,将其迁移到 git 可能就得不偿失了。
4、使用 GIT 以外的 配置源
在 Spring Cloud Config 中使用 git 以外的其他配置源时时,指的其实是服务器组件。对数据存储的选择不会影响客户端组件。只有服务器会受到影响。
在 Spring Cloud Config Server 库中,有一个名为 EnvironmentRepository
的接口定义了一个配置源。所有配置源(包括 git 和其他配置源)都必须实现该接口。
让我们来看看所提供的一些实现。
3.1、文件系统
Spring Cloud Config 支持将文件系统用作配置源。要启用此功能,必须在配置服务器的 application.properties
文件中指定以下值:
spring.cloud.config.server.native.search-locations=resources/other.properties
默认情况下,搜索位置假定为 classpath
下的资源。如果我们想使用任意文件,只需包含一个 file
资源前缀即可:
spring.cloud.config.server.native.search-locations=file:///external/path/other.properties
除此属性外,配置服务器还需要启用 native Profile:
-Dspring.profiles.active=native
在使用文件系统配置源时,需要确保文件系统在配置服务器运行的任何地方都是可用的。这可能意味着要使用 NFS 等分布式文件系统。
3.2、JDBC
Spring Cloud Config 也可以使用关系型数据库通过 JDBC 加载配置数据。这是通过 JdbcEnvironmentRepository
类实现的。要启用此类,我们需要按照几个步骤进行操作。
首先,classpath 上必须有 spring-jdbc 库。如果已经在使用 Spring Data JDBC 或其他依赖,那么它就已经存在了。否则,需要手动指定:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
其次,需要指定如何连接数据库:
spring.datasource.url=jdbc:mysql://dbhost:3306/springconfig
spring.datasource.username=dbuser
spring.datasource.password=dbpassword
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
在本例中,使用的是 MySQL,但任何兼容 JDBC 的驱动程序都可以使用。
接下来,数据库必须包含一个名为 PROPERTIES
的表,该表有以下列:
- APPLICATION
- PROFILE
- LABEL
- KEY
- VALUE
最后,需要为配置服务器指定 JDBC Profile:
-Dspring.profiles.active=jdbc
3.3、Redis
Spring Cloud Config 还支持将 Redis 作为配置源。这是通过 RedisEnvironmentRepository
类实现的。与 JDBC 源类似,需要遵循几个步骤来启用它。
首先,需要添加 Spring Data Redis 依赖:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
其次,需要为如何连接 Redis 设置一些属性:
spring.redis.host=localhost
spring.redis.port=6379
接下来,必须确保属性正确存储在 Redis 中。可以使用 HMSET
命令来存储一些示例属性:
HMSET application sample.property.name1 "somevalue" sample.property.name2 "anothervalue"
使用 HGETALL
查看数据:
HGETALL application
{
"sample.property.name1": "somevalue",
"sample.property.name2": "anothervalue"
}
最后,必须为 Spring Cloud Config 服务器启用 Redis Profile:
-Dspring.profiles.active=redis
使用 Redis 作为配置源还支持不同的 Profile。为此,只需在 application 末尾添加 Profile 名称即可:
HMSET application-dev sample.property.name1 "somevalue" sample.property.name2 "anothervalue"
如上,在名为 dev
的 Profile 下创建一组新属性。
3.4、Secrets
Secrets 是许多云服务商的常用功能。Secrets 允许我们将敏感数据作为云基础设施的一部分进行安全存储。对于用户名、主机名和密码等我们希望作为应用配置一部分的内容来说,Secrets 是再好不过的了。
Spring Cloud Config 支持许多不同的云 Secret 提供商。下面,我们将介绍 AWS,它使用 AwsSecretsManagerEnvironmentRepository
类将 AWS Secrets 加载到属性源中。
该类依赖 AWSSecretsManager
类来完成与 AWS 通信的繁琐工作。虽然我们可以自己手动创建,但更直接的解决方案是使用 Spring Starter:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws-secrets-manager-config</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
该模块包含一个自动配置,可为我们创建一个 AWSSecretsManager
实例。我们只需在 bootstrap.yml
文件中指定一组属性即可:
aws:
secretsmanager:
default-context: application
prefix: /config
profile-separator: _
fail-fast: true
name: ConfigServerApplication
enabled: true
现在,假设我们想将数据库凭证存储在 secret 中,并将其提供给配置服务器。我们只需在 /config/application/database_credentials
路径下创建一个新的 secret。并在其中存储连接数据库所需的键/值对。
这种结构还支持不同的 Profile。例如,如果我们有一个开发数据库服务器,我们也可以为它创建一个单独的 Secret。可以将其命名为 /config/application/database_credentials_dev
。
3.5、S3
另一种方便的配置存储方式是使用云文件服务。如 AWS S3。
首先,在项目中添加 AWS SDK:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3outposts</artifactId>
<version>1.12.150</version>
</dependency>
然后,需要提供一些值来配置与包含 property 文件的 S3 bucket 的连接:
amazon.s3.access-key=key
amazon.s3.secret-key=secret
此外,还需要为 AWS S3 Configuration Provider 提供特定属性:
spring:
cloud:
config:
server:
awss3:
region: us-east-1
bucket: config-bucket
还需要设置一个 Profile,以确保加载 AWS S3 配置源:
-Dspring.profiles.active=awss3
剩下的工作就是在 bucket 内创建我们所需的 properties 文件,包括任何特定于 Profile 的文件。注意,当应用没有 Profile 时,配置服务器会假定为 default
。因此,应在其他包含特定 Profile 名称的文件中加入一个带有该后缀的文件。
3.6、自定义配置源
如果上述提供的配置源不能满足我们的需求,可以选择实现我们自己的配置源。一般来说,这需要创建一个同时实现 EnvironmentRepository
和 Ordered
的新类:
public class CustomConfigurationRepository implements EnvironmentRepository, Ordered {
@Override
public Environment findOne(String application, String profile, String label) {
// 返回一个新 Environment,该 Environment 由所需的数据源(数据库、NoSQL 存储等)填充
}
@Override
public int getOrder() {
// 定义相对于其他 Configuration Repository
return 0;
}
}
然后,只需将该类实例化为一个新的 Spring Bean:
@Bean
public CustomConfigurationRepository customConfigurationRepository() {
return new CustomConfigurationRepository();
}
4、多配置源
在某些情况下,可能需要使用多个配置源运行 Spring Cloud Config。在这种情况下,必须指定几项数据。
比方说,我们希望同时使用 JDBC 和 Redis 作为配置源。需要做的第一件事就是在 bootstrap.yml
文件中定义每个源的顺序:
spring:
cloud:
config:
server:
redis:
order: 2
jdbc:
order: 1
这样,就可以指定哪些配置源应优先于其他配置源使用。排序遵循正常的 Spring Ordered
注解处理方式,值较小的配置源将首先被检查。
此外,还需要为服务器定义两个 Profiles:
-Dspring.profiles.active=jdbc,redis
注意,也可以在 YAML 中指定激活的 Profile。同样的模式也可用于定义任意数量的配置源。
5、总结
本文介绍了 Spirng Cloud Config 如何使用除 GIT 以外的配置源,如:文件系统、JDBC(关系型数据库)、Redis、Secrets、S3 和自定义的配置源。
参考:https://www.baeldung.com/spring-cloud-config-without-git