分布式系统面临的---配置问题
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。
SpringCloud提供了ConfigServer来解决这个问题,我们每一个微服务自己带着一个application.yml,上百个配置文件的管理......
是什么
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
SpringCloud Config分为服务端和客户端两部分。
服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口
官网学习地址
https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.2.1.RELEASE/reference/html/
能干嘛
集中管理配置文件
不同环境不同配置,动态化的配置更新,分环境部署比如dev/test/prod/beta/release
运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置
将配置信息以REST接口的形式暴露
与GitHub整合配置
由于SpringCloud Config默认使用Git来存储配置文件(也有其它方式,比如支持SVN和本地文件),
但最推荐的还是Git,而且使用的是http/https访问的形式
实战代码演示1(测试通过Config微服务可以从GitHub上获取配置内容)
前期准备:
用你自己的账号在GitHub上新建一个名为springcloudConfig的新Repository
由上一步获得刚新建的git地址 :
https://github.com/zhangzhihong123123/springcloudConfig.git
本地硬盘目录上新建git仓库并clone
git clone git@github.com:zzyybs/springcloud-config.git
将克隆的文件推送到自己的远程库中
新建Module模块cloud-config-center-3344;它即为Cloud的配置中心模块cloudConfig Center
pom文件
版本号已由父工程控制:
<!-- 统一管理jar包版本 --> <!-- 统一管理jar包版本 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <junit.version>4.12</junit.version> <log4j.version>1.2.17</log4j.version> <lombok.version>1.16.18</lombok.version> <mysql.version>8.0.16</mysql.version> <druid.version>1.1.16</druid.version> <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version> </properties>
<?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>mscloud</artifactId> <groupId>com.atguigu.springcloud</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> </project>
yml文件:
server: port: 3344 spring: application: name: cloud-config-center #注册进Eureka服务器的微服务名 cloud: config: server: git: uri: https://github.com/zhangzhihong123123/springcloudConfig.git #GitHub上面的git仓库名字 ####搜索目录 search-paths: - springcloud-config ####读取分支 label: main #服务注册到eureka地址 eureka: client: service-url: defaultZone: http://localhost:7001/eureka
eureka注册中心自行配置
主启动类
@SpringBootApplication @EnableConfigServer public class ConfigCenterMain3344 { public static void main(String[] args) { SpringApplication.run(ConfigCenterMain3344.class, args); } }
@EnableConfigServer 加入该注解,开启配置中心服务
windows下修改hosts文件,增加映射(也可以不用操作)
127.0.0.1 config-3344.com
启动微服务3344
访问http://config-3344.com:3344/main/config-dev.yml
如果映射文件没加可访问http://localhost:3344/main/config-dev.yml
结果:
配置读取规则
/{label}/{application}-{profile}.yml
main/config-dev.yml
只需要掌握一种就好
label:分支 如:master分支,dev分支
application:服务名
profile:环境(dev/test/prod)
bootstrap.yml 文件解释
实战代码演示2(实现客户端3355访问SpringCloud Config3344通过GitHub获取配置信息)
新建cloud-config-client-3355
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>cloud2020</artifactId> <groupId>com.atguigu.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-config-client-3355</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <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> </dependencies> </project>
yml文件
server: port: 3355 spring: application: name: config-client cloud: #Config客户端配置 config: label: main #分支名称 name: config #配置文件名称 profile: dev #读取后缀名称 上述3个综合:main分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml uri: http://localhost:3344 #配置中心地址k #服务注册到eureka地址 eureka: client: service-url: defaultZone: http://localhost:7001/eureka
config:
label: main #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述3个综合:main分支上config-dev.yml的配置文件被读取
http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址k
主启动类
@EnableEurekaClient @SpringBootApplication public class ConfigClientMain3355 { public static void main(String[] args) { SpringApplication.run(ConfigClientMain3355.class,args); } }
业务类
@RestController public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo() { return configInfo; } }
测试 1
http://config-3344.com:3344/main/config-prod.yml
测试2:
http://config-3344.com:3344/main/config-dev.yml
测试3:
http://localhost:3355/configInfo
测试3可以发现实现了客户端3355访问SpringCloud Config3344通过GitHub获取配置信息
新问题
问题随时而来,分布式配置的动态刷新问题
1.Linux运维修改GitHub上的配置文件内容做调整
2.刷新3344,发现ConfigServer配置中心立刻响应
3.刷新3355,发现ConfigClient客户端没有任何响应
4.3355没有变化除非自己重启或者重新加载
5.难到每次运维修改配置文件,客户端都需要重启??噩梦
实战代码演示3(避免每次更新配置都要重启客户端微服务3355)
修改3355模块
pom文件添加新的依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
修改YML,暴露监控端口
server: port: 3355 spring: application: name: config-client cloud: #Config客户端配置 config: label: master #分支名称 name: config #配置文件名称 profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取 uri: http://localhost:3344 #配置中心地址k #服务注册到eureka地址 eureka: client: service-url: defaultZone: http://localhost:7001/eureka # 暴露监控端点 management: endpoints: web: exposure: include: "*"
@RefreshScope业务类Controller修改
@RestController @RefreshScope public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo() { return configInfo; } }
测试 1:
此时修改github---> 3344 ---->3355,即改version=8
config-3344.com:3344/main/config-dev.yml
localhost:3355/configInfo
3355改变没有没有达到效果
原因:
需要运维人员发送Post请求刷新3355
必须是POST请求
curl -X POST "http://localhost:3355/actuator/refresh"
测试2:
发现已经更改