SpringCloud系列文章列表
0. SpringCloud实战专栏介绍准备
1. SpringCloud父工程搭建
2. 服务注册中心之Eureka(单机+集群+Ribbon调用)
3. 服务注册中心之Zookeeper
4. 服务注册中心之Consul
5. eureka、zookeeper和consul三种注册中心之间的区别
6. 负载均衡服务调用之Ribbon
7. 服务调用之OpenFeign
8. Hystrix断路器全面实战总结
9. SpringCloud Gateway网关
10. SpringCloud Config配置中心
11. SpringCloud Bus消息总线
12. SpringCloud Stream消息驱动
13. SpringCloud Sleuth分布式请求链路追踪
目录
前言
***分布式系统面临的配置问题?
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以—套集中式的、动态的配置管理设施是必不可少的。
所以SpringCloud Config就来了
1 SpringCloud Config介绍
官方文档:
https://docs.spring.io/spring-cloud-config/docs/2.2.5.RELEASE/reference/html/
中文 https://www.springcloud.cc/spring-cloud-config.html
1.1 是什么?
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
1.2 怎么玩?
SpringCloud Config分为服务端和客户端两部分。
-
服务端
服务端也称为分布式配置中心,它是一个独立的微服务应用, 用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口 -
客户端
客户端则是通过指定的配置中心(即服务端)来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。
配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,组可以通过git客户端工具来方便的管理和访问配置内容
1.3 能干嘛?
- 集中管理配置文件
- 不同环境不同配置动态化的配置更新,分环境部署比如dev/test/prod/beta/release
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
- 当配置发生改动时,服务不需要重启即可感知到配置的变化并应用新的配置
- 将配置信息以REST接口的形式暴露(post、curl访问刷新均可)
2 代码实战
配置中心Config Server从git仓库获取配置信息
客户端 Client 从配置中心获取配置信息
2.1 配置服务器配置
默认使用git来存储配置文件,
本文git仓库采用gitee演示,github其实都差不多
2.1.1 新建仓库增加配置文件
我的仓库 https://gitee.com/shuaidawang/springcloud-config
新建仓库springcloud-config
master分支:
- config-dev.yml
config:
info: "master branch,config-repo config-dev.yml version=0"
- config-prod.yml
config:
info: "master branch,config-repo config-prod.yml version=0"
- config-test.yml
config:
info: "master branch,config-repo config-test.yml version=0"
dev分支:
- config-dev.yml
config:
info: "dev branch,config-repo config-dev.yml version=0"
- config-prod.yml
config:
info: "dev branch,config-repo config-prod.yml version=0"
- config-test.yml
config:
info: "dev branch,config-repo config-test.yml version=0"
ok, 配置文件准备完毕
2.1.2 ssh协议公钥配置
如果要用ssh地址访问仓库,则需要此配置;如果是https,则跳过
公钥设置方法参考官网 https://gitee.com/help/articles/4181#article-header0
2.2 Config配置中心
2.2.1 项目代码
新建项目cloud-config-center3344
- pom.xml
<!--config 服务中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- application.yml
server:
port: 3344
spring:
application:
name: cloud-config-center
cloud:
config:
server:
git:
#uri: https://gitee.com/shuaidawang/springcloud-config.git #https 需要配用户名和密码
#username: shuaidawang
#password: 1
uri: git@gitee.com:shuaidawang/springcloud-config.git #ssh 需要配置公钥
search-paths: #搜索目录
- springcloud-config
label: master #分支
#eureka配置
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
- 启动类
增加注解 @EnableConfigServer
测试
启动cloud-eureka-server7001、cloud-config-center3344
-
浏览器 访问http://localhost:3344/master/config-dev.yml
获取master分支的config-dev.yml配置信息
-
浏览器 访问http://localhost:3344/dev/config-dev.yml
获取dev分支的config-dev.yml配置信息
成功实现了用SpringCloud Config通过Gitee获取配置信息
2.2.2 配置读取规则
参考官网
label 分支,默认是master;
profile 环境(如dev、test、prod等);
application 配置文件名称
最推荐使用第三种 /{label}/{application}-{profile}.yml
*经测试发现, /{label}/{application}-{profile}.yml中的-{profile}可以省略为/{label}/{application}.yml
2.3 Config客户端
2.3.1 项目代码
新建项目cloud-config-client3355
- pom.xml
<!--SpringCloud-config-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- bootstrap.yml
什么是bootstrap.yml?
applicaiton.yml是用户级的资源配置项, bootstrap.yml是系统级的,优先级更加高
Spring Cloud会创建一个“BootstrapContext”,作为Spring应用的’Application Context的父上下文。初始化的时候,BootstrapContext'负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的
Environment’。
'Bootstrap’属性有高优先级,默认情况下,它们不会被本地配置覆盖。Bootstrap context和Application Context有着不同的约定,所以新增了一个'bootstrap.yml'文件,保证
Bootstrap Context和Application Context'
配置的分离。
要将Client模块下的application.yml文件改为bootstrap.yml,这是很关键的,
因为bootstrap.yml是比application.yml先加载的。bootstrap.yml优先级高于application.yml
server:
port: 3355
spring:
application:
name: config-client
cloud:
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 即读取master分支的config-dev.yml配置文件
uri: http://localhost:3344
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
- 启动类
普通Springboot启动类,无额外注解 - web类
写个web接口获取3344配置文件中config.info,便于测试能否获取到
@RestController
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo(){
return configInfo;
}
}
测试
启动cloud-eureka-server7001、cloud-config-center3344、cloud-config-client3355
浏览器访问http://localhost:3355/configInfo
成功实现了客户端3355访问SpringCloud Config3344通过git获取配置信息;
2.3.2 目前存在的问题
再次测试
- 此时修改gitee上 master分支,config-dev.yml的version由0改为1,如下图
- 浏览器访问 http://localhost:3344/config-dev.yml
发现3344Config配置中心立刻获取到了最新的配置文件;
- 浏览器访问http://localhost:3355/configInfo
发现3355客户端并没有获取到最新的配置文件;当3355重启后,才能获取到最新的配置;
总结:当配置服务器的配置文件发生更新;配置中心立刻能获取到最新的配置文件,而客户端得重启后才能获取最新配置;
实际分布式服务中有n多个客户端,一个个重启不太现实。所以要解决这个问题;即Config客户端之动态刷新
2.4 Config客户端之动态刷新
为了避免每次都要重启客户端获取最新配置的问题;
2.4.1 项目代码
修改cloud-config-client3355客户端模块
- 修改pom.xml,引入actuator
之前已经引入,不用再次引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- bootstrap.yml
# 暴露端口
management:
endpoints:
web:
exposure:
include: "*"
- web类
新增注解@RefreshScope
@RestController
@RefreshScope
public class ConfigClientController {
测试
重启cloud-config-client3355项目,
-
修改配置服务器中的master分支,config-dev.yml的version由1改为2
-
访问http://localhost:3355/configInfo ,发现没变化
-
发送post请求。 curl -X POST “http://localhost:3355/actuator/refresh”
再次访问
实现了不重启的情况下,客户端3355获取到最新的配置内容;
3 思考
虽然最终实现了不重启的情况下,客户端获取最新配置;但是在分布式系统中,客户端特别特别多,每一个都要发送post请求通知,特别恶心、麻烦,累死个球来。
能不能采用广播的方式,一次通知,处处生效?
答案就是SpringCloud Bus消息总线,下节继续!
点赞+评论+关注
本文源码地址: https://gitee.com/shuaidawang/SpringCloudDemo.git
有错误的地方欢迎各位大佬指正!可以加入qq交流群: 700637673