spring-cloud-config-server2.0使用ETCD存储配置文件
实现目标:使用ETCD来实现spring-cloud-config-server的配置文件存储功能
官方说明参考:https://docs.spring.io/spring-cloud-config/docs/2.2.9.BUILD-SNAPSHOT/reference/html/#_custom_composite_environment_repositories
config-server实现
Spring Boot版本和 Spring cloud版本需要保持一致
- maven版本坐标
//仅列出主要版本配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.10.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 创建自定义的属性配置类
@Component
@ConfigurationProperties("spring.cloud.config.server.etcd")
public class EtcdEnvironmentProperties implements EnvironmentRepositoryProperties {
private int order = Ordered.LOWEST_PRECEDENCE;
//etcd服务地址
private String serverUrl;
public int getOrder() {
return this.order;
}
@Override
public void setOrder(int order) {
this.order = order;
}
public String getServerUrl() {
return serverUrl;
}
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
}
- 实现EnvironmentRepository,并使用注解
@Profile("etcd")
@Profile("etcd") //自定义的EnvironmentRepository, 用法application.properties中使用: spring.profiles.active=etcd
@Configuration
public class EtcdEnvironmentRepository implements EnvironmentRepository, Ordered {
private EtcdClient etcdClient;// EtcdClient的java客户端
private EtcdEnvironmentProperties etcdEnvironmentProperties; //
public EtcdEnvironmentRepository(EtcdClient etcdClient, EtcdEnvironmentProperties etcdEnvironmentProperties) {
etcdClient.setUrl(etcdEnvironmentProperties.getServerUrl());
etcdClient.connect();
this.etcdClient = etcdClient;
this.etcdEnvironmentProperties = etcdEnvironmentProperties;
}
//此方法为具体实现业务逻辑
@Override
public Environment findOne(String application, String profile, String label) {
String[] profiles = StringUtils.commaDelimitedListToStringArray(profile);
Environment environment = new Environment(application, profiles, label, null, null);
final List<String> keys = addKeys(application, profile);
keys.forEach(it -> {
environment.add(new PropertySource(it, etcdClient.read2Properties(it)));
});
return environment;
}
//支持多个profile和 application name
private List<String> addKeys(String application, String profile) {
List<String> keys = new ArrayList<>();
String[] apps = StringUtils.commaDelimitedListToStringArray(application);
String[] profiles = StringUtils.commaDelimitedListToStringArray(profile);
for (String prof : profiles) {
for (String app : apps) {
keys.add(app + "-" + prof + ".properties");
}
}
return keys;
}
@Override
public int getOrder() {
return etcdEnvironmentProperties.getOrder();
}
}
- 配置文件
spring.application.name=config-server
server.port=1202
eureka.client.register-with-eureka=false
spring.profiles.active=etcd #重要,指定使用etcd,EtcdEnvironmentRepository为实现类
spring.cloud.config.server.etcd.serverxx-url=http://ip:2379
客户端使用
- maven坐标
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.10.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
- application配置
spring.cloud.config.profile=dev,public #支持多个profile
spring.cloud.config.name=demo-service,demo-mysql,demo-amq #支持多个配置文件
spring.cloud.config.uri=http://ip:port #config-server地址
写在最后
- 如上写法仅支持 properties文件,yml等其他格式支持,需药etcd的client中做转换
- 如上实现可以使用Spring cloud生态,使用方法和习惯和官方保持一致
- 本文仅讨论etdc的实现方式,具体项目实践中,以具体需求为准,不代表etcd优于git、native、jdbc等实现