一、概述
1、分布式系统面临的配置问题
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。
因此,SpringCloud提供了ConfigServer来解决这个问题。
2、 Config配置中心是什么
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
SpringCloud Config分为服务端和客户端两部分。
服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。
客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。
3、Spring Config能做什么
(1)集中管理配置文件;
(2)不同环境不同配置,动态化的配置更新,分环境部署比如dev、test、prod、beta、release;
(3)运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息;
(4)当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置;
(5)将配置信息以REST接口的形式暴露;
(6)……
由于SpringCloud Config默认使用Git来存储配置文件(也有其它方式,比如支持SVN和本地文件),但最推荐的还是Git,而且使用的是http/https访问的形式。
二、Config总控中心配置与测试
1、在Gitee上新建仓库
新建名为springcloud-config 的仓库
2、本地硬盘目录上新建git仓库并clone
git clone 仓库地址(最好是http的)
Git相关的知识就不多赘述了,可以参考我的博客
Git学习(四):GitHub远程库操作_m0_49499183的博客-CSDN博客
3、在IDEA中新建模块
新建普通maven模块 cloud-config-center-3344
4、修改pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud</artifactId> <groupId>com.shang.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-config-center-3344</artifactId> <dependencies> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> </project>
5、编写yml文件
server: port: 3344 spring: application: name: cloud-config-center #注册进Eureka服务器的微服务名 cloud: config: server: git: uri: https://gitee.com/jade-faced-dragon/springcloud-config.git #Gite上面的git仓库名字 ####搜索目录 search-paths: - springcloud-config ####读取分支 label: master #服务注册到eureka地址 eureka: client: service-url: defaultZone: http://localhost:7001/eureka
6、编写主启动类(加上@EnableConfigServer注解)
@SpringBootApplication @EnableConfigServer public class ConfigCenterMain3344 { public static void main(String[] args) { SpringApplication.run(ConfigCenterMain3344.class, args); } }
7、windows下修改hosts文件,增加映射
host文件的地址 C:\Windows\System32\drivers\etc
在文件最后加上
127.0.0.1 config-3344.com
修改之前最好还是将host文件备份一份,避免误操作。
8、运行测试
启动eureka7001、config3344.
http://config-3344.com:3344/master/README.md
可以访问到仓库中的内容。
这说明如果仓库中有各个微服务的yml配置文件,我们也是可以读取到的。
9、读取规则
/{label}/{application}-{profile}.yml
例如:master分支下,config服务的dev环境:
http://config-3344.com:3344/master/config-dev.yml
三、Config客户端配置与测试
1、新建模块
新建普通maven模块cloud-config-client-3355
2、修改pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud</artifactId> <groupId>com.shang.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-config-client-3355</artifactId> <dependencies> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> <version>3.0.3</version> </dependency> </dependencies> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> </project>
3、编写yml文件
这次的yml文件为bootstrap.yml。
(1)什么是bootstrap.yml
applicaiton.yml是用户级的资源配置项;bootstrap.yml是系统级的,优先级更加高
Spring Cloud会创建一个“Bootstrap Context”,作为Spring应用的`Application Context`的父上下文。初始化的时候,`Bootstrap Context`负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的`Environment`。
`Bootstrap`属性有高优先级,默认情况下,它们不会被本地配置覆盖。 `Bootstrap context`和`Application Context`有着不同的约定,所以新增了一个`bootstrap.yml`文件,保证`Bootstrap Context`和`Application Context`配置的分离。
(2)内容
server: port: 3355 spring: application: name: config-client cloud: #Config客户端配置 config: label: master #分支名称 name: config #配置文件名称 profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml uri: http://localhost:3344/X #配置中心地址k #服务注册到eureka地址 eureka: client: service-url: defaultZone: http://localhost:7001/eureka
4、编写主启动类
@SpringBootApplication @EnableEurekaClient public class ConfigClientMain3355 { public static void main(String[] args) { SpringApplication.run(ConfigClientMain3355.class, args); } }
5、创建config-dev.yml,并提交到Gitee中
1. config: 2. info: master branch,springcloud-config/config-prod.yml version=1
6、编写逻辑代码
config包中
@RestController public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo() { return configInfo; } }
7、运行测试
http://localhost:3355/configInfo
也可以获取到config-dev.yml中的内容
8、问题随之而来
当Gitee中的配置文件修改后,刷新3344,页面中的内容马上改变;而刷新3355则不会改变,必须重启3355.那么,难道每次运维修改配置文件,客户端都需要重启?这是我们需要解决的问题:分布式配置的动态刷新问题。
这就是下面要讲到的.
四、Config动态刷新
1、在POM文件中引入actuator监控
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
2、在yml中添加暴露监控端口
# 暴露监控端点 management: endpoints: web: exposure: include: "*"
3、在业务类controller类上增加@RefreshScope注解
4、修改Gitee上的配置文件,模拟运维人员修改配置
例如,将版本号从1改为2.
5、模拟运维人员发送post请求,手动刷新
在git本地仓库下的命令行中输入命令:
curl -X POST "http://localhost:3355/actuator/refresh"
6、刷新3344和3355 ,看是否更新
可以看出,已经3355能够更新了。
6、是不是还可以改进
假如我们有很多的服务3355、3366、3377……,那是不是要给每一个服务发送一次手动刷新的post请求呢? 能不能做到只发送一次请求,让每个服务都收到更新通知,一次广播,处处生效呢?这就需要用到我们下篇文章要讲到的Bus消息总线。