前言
Github:https://github.com/yihonglei/thinking-in-springcloud
config服务端:config-server
config客户端:config-client
config配置中心:
https://github.com/yihonglei/lanhuigu-cloud-config(文件路径)
https://github.com/yihonglei/lanhuigu-cloud-config.git(git地址,公开路径,无需权限访问)
一 config概述
Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。
将你的配置放在远程,然后本地从远程获取配置。示意图:
Config服务端特性:
- HTTP,为外部配置提供基于资源的API(键值对,或者等价的YAML内容);
- 属性值的加密和解密(对称加密和非对称加密);
- 通过使用@EnableConfigServer在Spring boot应用中非常简单的嵌入;
Config客户端的特性(特指Spring应用):
- 绑定Config服务端,并使用远程的属性源初始化Spring环境;
- 属性值的加密和解密(对称加密和非对称加密);
二 config-server(config服务端)
从远程地址拉取配置文件。
1、项目结构
2、pom.xml
<!-- config-server依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
3、application.yml
server:
port: 9004
spring:
application:
name: config-server
cloud:
config:
server:
git:
# git为public权限,可以不加用户名、密码访问
uri: https://github.com/yihonglei/lanhuigu-cloud-config.git
username:
password:
4、ConfigServerApplication(启动类)
package com.lanhuigu.config.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
/**
* config服务端,负责拿到远端地址内容,比如git
*
* @auther: yihonglei
* @date: 2019-07-15 17:24
*/
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
@EnableConfigServer启动config server注解。
5、获取配置
1)配置中心内容
2)获取application-dev.yml配置内容
http://localhost:9004/master/application-dev.yml
可以通过http://localhost:9004/master/application-test.yml获取测试配置内容。
访问配置中心文件规则如下:
通过{application}-{profiles}.yml访问,比如:http://localhost:9004/application-test.yml
通过/{application}/{profiles}/{label}访问,比如:http://localhost:9004/application/test/master
通过/{label}/{application}-{profiles}.yml访问,比如:http://localhost:9004/master/application-test.yml
如果是properties文件,通过/{application}-{profile}.properties或/{label}/{application}-{profile}.properties访问。
三 config-client(config客户端)
1、项目结构
2、pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
3、application.yml
spring:
application:
name: order
server:
port: 8001
config-client工程配置spring.application.name=config-client,server.port=8001。
4、bootstrap.yml
# config-client从config-server获取配置,config-server从远程git获取配置
# 将获取的配置,替换掉config-client工程中的application.yml配置内容。
# 包括spring.application.name和server.port。
# 配置会组成请求config-server地址,获取内容order-dev.yml里面dev内容:
# http://localhost:9004/master/order-dev.yml
spring:
application:
name: order
cloud:
config:
uri: http://localhost:9004/
profile: dev
label: master
spring.application.name=order,order对应为访问路径的{application};
spring.cloud.config.uri配置config-server端服务地址;
spring.cloud.config.profile=dev,dev为对应访问路径的{profiles};
spring.cloud.config.label=master,master对应为访问路径的{label};
config-client会根据请求地址去服务端获取配置并替换掉config-client工程的application.yml里面的配置。
注意:bootstrap.yml和application.yml里面的spring.application.name保持一致或只保留bootstrap里面的
spring.application.name配置。
理论上boostrap.yml所有属性加载顺序优先于application.yml,但是不要挑战Spring Boot文件加载顺序机制。
5、ConfigController(测试控制层)
package com.lanhuigu.config.client.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* 从配置中心获取配置。
* config-client-->config-server-->git
*
* @author yihonglei
* @date 2019-07-15 17:58
*/
@RestController
public class ConfigController {
@Value("${spring.application.name}")
private String applicationName;
@Value("${server.port}")
private Integer serverPort;
@RequestMapping("/getConfigRemote")
public Map<String, Object> getConfig4Remote() {
Map<String, Object> retMap = new HashMap<>();
retMap.put("applicationName", applicationName);
retMap.put("port", serverPort);
return retMap;
}
}
6、ConfigClientApplication(启动类)
package com.lanhuigu.config.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* config客户端,负责从config服务端获取内容
*
* @auther: yihonglei
* @date: 2019-07-15 17:57
*/
@SpringBootApplication
public class ConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication.class, args);
}
}
7、服务访问和分析
1)启动服务,访问ConfigController
请求地址:http://localhost:9001/getConfigRemote
2)逻辑分析
config-client的application.yml配置的端口是8001,理论上我们访问config-client应该也要用8001,
实际上使用的是9001,这个9001是根据bootstrap.yml配置从config-server端获取order-dev.yml文件,
并将内容覆盖掉application.yml中相同属性的值,所以,config-client用的是配置中心获取的值。
四 动态刷新配置
当你的服务正在运行的时候,在配置中心修改配置,服务是不会自动拿到最新配置的。
我们可以通过手动方式在不启动服务的前提下刷新配置,让服务拿到最新配置。
1、pom.xml
在config-client的pom.xml中增加监控包。
<!-- 监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、开放监控端口
在config-client的bootstrap.yml中增加开放监控端口配置。
# 开放监控端口
management:
endpoints:
web:
exposure:
include: "*"
bootstrap.yml完整配置。
# config-client从config-server获取配置,config-server从远程git获取配置
# 将获取的配置,替换掉config-client工程中的application.yml配置内容。
# 配置会组成请求config-server地址,获取内容order-dev.yml里面dev内容:
# http://localhost:9004/master/order-dev.yml
spring:
application:
name: order
cloud:
config:
uri: http://localhost:9004/
profile: dev
label: master
# 开放监控端口
management:
endpoints:
web:
exposure:
include: "*"
3、添加@RefreshScope注解
在使用配置的类上面加上@RefreshScope命令。
这里在config-client的ConfigController上添加@RefreshScope注解。
package com.lanhuigu.config.client.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* 从配置中心获取配置。
* config-client-->config-server-->git
*
* @author yihonglei
* @date 2019-07-15 17:58
*/
@RestController
@RefreshScope
public class ConfigController {
@Value("${spring.application.name}")
private String applicationName;
@Value("${server.port}")
private Integer serverPort;
@RequestMapping("/getConfigRemote")
public Map<String, Object> getConfig4Remote() {
Map<String, Object> retMap = new HashMap<>();
retMap.put("applicationName", applicationName);
retMap.put("port", serverPort);
return retMap;
}
}
4、启动服务
config-server和config-client。
访问config-client,http://localhost:9001/getConfigRemote
将配置中心spring.application.name修改为order-dev-tt。
再次访问http://localhost:9001/getConfigRemote ,返回的applicationName还是修改前的order-dev,
并不是最新的order-dev-tt。
调用刷新接口http://localhost:9001/actuator/refresh,返回结果:
说明刷新成功,这个请求是post请求。
再次访问http://localhost:9001/getConfigRemote,返回最新的配置。