consul 除了作为服务发现以外,还有一个重要的功能,可以作为配置中心,从而替换 Spring Cloud Config 的 client-server 配置模式。利用 consul 提供的 key-value 数据存储功能,来实现使用 consul 中的配置覆盖应用程序中的配置。
首先需要知道 Spring Boot 项目还有一个配置文件叫做 bootstrap.yml ,这个配置文件是在 Spring Boot 项目启动引导时载入,比 application.yml 文件更早加载。使用 Consul 作为配置中心,我们就需要把相关配置写入 bootstrap.yml 中。项目代码依旧以 《SpringCloud(Finchley.SR2版本)踩坑笔记(三)-------服务注册与消费》为例
spring:
application:
name: spring-cloud-service
cloud:
consul:
host: 10.150.1.99
port: 8500
discovery:
healthCheckPath: /service/health
healthCheckInterval: 15s
config:
# 启用配置
enable: true
# consul 中的 key-value 存储格式为 yaml
format: YAML
# consul 用于存储配置文件的根目录为 config
prefix: config
# 配置文件对应的应用名称
defaultContext: spring-cloud-service
# 多个配置文件的分割符
profileSeparator: ','
# 最后一层节点的key值名称,一般默认为data
data-key: data
然后,我们在 application.yml 文件中,声明一个配置值 user.name=local
user:
name: local
修改项目代码,输出配置文件中这个 name
@Value("${user.name}")
private String name;
@RequestMapping(value = "hello", method = RequestMethod.GET)
@ResponseBody
public String hello(@RequestParam String name) throws AnkonException {
String result = "hello " + name + ", you get the service, " + this.name;
return new RestJson(result).toJson();
}
此时,访问 http://localhost:9090/service/hello?name=张三 可以得到如下访问结果
然后在 consul 的管理后台中,我们添加相关的key-value值来改变这个变量
此间第二步设置的路径就需要跟据 bootstrap.yml 中配置来具体对应填写。然后重启项目,再次访问 http://localhost:9090/service/hello?name=张三,我们即可看到name的值变化了
如果你运行的不是默认配置文件,比如 dev, test, prod 等配置文件,那么需要修改 name 值时,需要修改写入的 key-value 路径,比如 dev 配置
这时,使用 java -Dspring.profiles.active=dev -jar service.jar 运行 dev 配置,则会去加载这个dev配置下的name值,访问 http://localhost:9090/service/hello?name=张三 即可看到如下结果:
按照上述方式,我们成功修改了 application.yml 中项目实际运行时的某些变量,但是有一个弊端,每次修改完一个值之后,必须要重启项目,这样是一个比较麻烦的事情,我们可以通过 @ConfigurationProperties 来读取注入 yml 中的变量值,这样在 consul 中修改修个值的时候,代码中的值也会相应的修改掉。
首先,添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
然后写一个注入类:
package com.ankon.service1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "user")
public class Config implements EnvironmentAware {
private final static Logger LOGGER = LoggerFactory.getLogger(Config.class);
private String name;
//存储从环境变量读取的当前激活的配置文件名
private String activeProfile;
@Override
public void setEnvironment(Environment e) {
if (e.getActiveProfiles() != null && e.getActiveProfiles().length > 0) {
this.activeProfile = e.getActiveProfiles()[0];
LOGGER.info("Active Profile:[" + this.activeProfile + "]");
} else {
LOGGER.info("Active Profile:[null]");
}
}
public String getActiveProfile() {
return this.activeProfile;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
然后启动项目,按照之前的步骤在 consul 后台中修改变量值, 不用重启项目,访问 http://localhost:9090/service/hello?name=张三 可以看到 name 的值确实变化了。