1、为什么要统一管理微服务配置
- 集中管理配置——微服务架构中成百上千个微服务,需要集中管理
- 运行期间可动态调整——可在不重启微服务同时修改微服务配
2、SpringCloud Config简介
SpringCloud Config为分布式系统外部配置提供了服务器端和客户端的支持,包括ConfigServer和ConfigClient两部分。
3、编写ConfigServer
假如Git仓库现在有以下几个配置文件,内容分别为注释部分:
microservice-foo.properties //profile=default-1.0
microservice-foo-dev.properties //profile=dev-1.0
microservice-foo-test.properties //profile=test-1.0
microservice-foo-production.properties //profile=production-1.0
3.1、添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
3.2、编写启动类
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
3.3、编写配置文件
server:
port: 8080
spring:
application:
name: microservice-config-server
cloud:
config:
server:
git:
uri: https://git.oschina.net/itmuch/spring-cloud-config-repo # 配置Git仓库的地址
username: # Git仓库的账号
password: # Git仓库的密码
启动项目之后,我们就可以通过访问ConfigServer项目,获取git上配置文件的信息,如下:
http://localhost:8080/microservice-foo-dev.properties
也有几种变形写法:
http://localhost:8080/microservice-foo/dev
http://localhost:8080/{分支}/microservice-foo/dev
4、编写ConfigClient
4.1、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
4.2、创建SpringBoot启动类
@SpringBootApplication
public class ConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication.class, args);
}
}
4.3、编写配置文件
application.yml
server:
port: 8081
bootstrap.yml
spring:
application:
name: microservice-foo # 对应config server所获取的配置文件的{application}
cloud:
config:
uri: http://localhost:8080/
profile: dev # profile对应config server所获取的配置文件中的{profile}
label: master # 指定Git仓库的分支,对应config server所获取的配置文件的{label}
SpringCloud有一个“引导上下文”的概念,这是主应用程序的父上下文。职责是从配置服务加载配置。bootstrap.yml中的配置有更高的优先级。注:如果要禁用引导过程,设置spring.cloud.bootstrap.enabled=false
4.4、编写Controller
@RestController
public class ConfigClientController {
@Value("${profile}")
private String profile;
@GetMapping("/profile")
public String hello() {
return this.profile;
}
}
此处 @Value("${profile}")就是从对应git上的配置文件中读取的参数
5、ConfigServer的Git仓库配置详解
前文spring.cloud.config.server.git.url指定了Git仓库,实际这里可以非常灵活
5.1、占位符支持
ConfigServer的占位符支持{application}、{profile}和{label}
server:
port: 8080
spring:
application:
name: microservice-config-server
cloud:
config:
server:
git:
uri: https://git.oschina.net/itmuch/{application} # 配置Git仓库的地址
username: # Git仓库的账号
password: # Git仓库的密码
5.2、模糊匹配
spring:
cloud:
config:
server:
git:
uri: https://git.oschina.net/itmuch/config-repo # 配置Git仓库的地址
repos:
simple: https://github.com/simple/config-repo
special:
pattern: special*/dev*,*special*/dev*
url: https://github.com/special/config-repo
local:
pattern: local*
uri: file:/home/configsvc/config-repo
该例中,simple仓库,只匹配所有配置文件中名为simple的应用程序
local仓库,则匹配所有配置文件以local开头的所有应用程序名称
5.3、搜索目录(略)
5.4、启动时加载配置文件(略)
6、ConfigServer健康状况指示器(略)
7、配置内容加解密(略)
8、使用/fresh端点手动刷新配置
在不重启项目的情况下,修改配置并且使配置生效,对ConfigClient要做如下修改
8.1、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
8.2、在Controller上添加@RefreshScope注解,该类就会在配置更新时得到特殊处理
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${profile}")
private String profile;
@GetMapping("/profile")
public String hello() {
return this.profile;
}
}
启动ConfigServer项目,启动ConfigClient项目,
请求localhost:8081/profile,看到一个结果。然后修改对应git上的配置文件
localhost:8081/refresh刷新配置,然后再请求localhost:8081/profile查看效果
9、使用Spring Cloud Bus自动刷新配置
/refresh刷新只能刷新一个节点,如果整个系统成百上千个微服务需要刷新配置,则需要Bus刷新来实现
9.1、Bus刷新简介
借助轻量级消息代理,如MQ,Kafka等,连接分布式系统的节点,这样就可以广播传播状态的更改。架构图如下:
9.2、Bus刷新的实现
前提是要有一个可用的RabbitMQ
9.2.1、添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
9.2.2、修改配置文件bootstrap.yml
spring:
application:
name: microservice-foo # 对应config server所获取的配置文件的{application}
cloud:
config:
uri: http://localhost:8080/
profile: dev # profile对应config server所获取的配置文件中的{profile}
label: master # 指定Git仓库的分支,对应config server所获取的配置文件的{label}
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
启动ConfigServer,以不同端口8081和8082启动两个修改后的ConfigClient,
访问http://localhost:8081/profile,得到一个结果,然后修改git上配置
post请求http://localhost:8081/bus/refresh
分别访问http://localhost:8081/profile,http://localhost:8082/profile两个节点,看是否都同步修改
9.3、局部刷新(略)
9.4、架构改进
考虑到微服职责单一原则,每个微服务不应该承担配置刷新的职责,将ConfigServer加入到消息总线中,通过对ConfigServer的/bus/refresh端点刷新来实现配置更新。
(略)
10、SpringCloud Config与Eureka配合使用
为了利用组件的整体优势,比如防止某个微服务ip或端口修改造成其他项目配置修改,ConfigServer和ConfigClient统一交给Eureka来管理。
10.1、将ConfigServer和ConfigClient项目都注册到Eureka Server里面
10.2、ConfigClient配置文件bootstrap.yml修改如下:
spring:
application:
name: microservice-foo # 对应config server所获取的配置文件的{application}
cloud:
config:
username: user
password: password123
profile: dev
label: master
discovery:
enabled: true #表示使用服务发现的configserver配置,而不是自己配置的ConfigServer的uri,默认false
service-id: microservice-config-server-eureka # 指定Config Server在服务发现中的serviceId,默认是configserver
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/