文章目录
SpringCloud - Config分布式配置中心
0. 概述
① 为什么需要Config:
每个微服务都需要一个配置文件,并且如果有几个微服务都需要连接数据库,那么就需要配4次数据库相关配置,并且当数据库发生改动,那么需要同时修改4个微服务的配置文件才可以。
微服务架构意味着将会产生越来越多的单体服务,每个业务模块都被拆成了一个微服务模块,每个微服务模块中,都有各自的配置文件,随着模块的增多,配置文件越来越多,因此,需要有一个集中式的、动态配置的管理来解决这个问题。于是Spring Cloud提供了Config类解决这个问题,它为微服务中的模块提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供一个中心化的外部配置。
② Spring Cloud Config分为服务端和客户端两部分:
服务端称为分布式配置中心 ,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。
客户端通过指定配置中心来管理应用资源以及与业务相关的配置内容,在启动的时候,从配置中心(服务端Config)读取加载配置信息,配置服务器默认采用git来存储配置信息,有助于对环境配置进行版本管理,可以通过git客户端工具方便管理和访问配置内容。
③ Config的功能:
- 集中管理配置文件
- 不同环境可以使用不同的配置,动态配置更新
- 运行期间,动态调整配置,不再需要在每个服务部署的机器上修改配置文件,服务回向配置中心统一拉取配置信息
- 当配置发生变化,服务不需要重启即可感知到配置的变化,并应用新的配置
- 将配置信息以REST接口形式暴露
1. 使用github作为配置中心的仓库
① 登录github账号,进行repository的创建,名称为springcloud-config
② 进入周阳老师该项目的github地址,然后将这个仓库克隆到本地: git clone https://github.com/zzyybs/springcloud-config.git
③ 进入克隆目录,将config-dev.yml、config-test.yml、config-prod.yml这三个配置文件推送到自己创建的远程仓库
④ 到此自己创建的仓库中便有了这三个文件:
2. SpringCloud Config服务端3344
SpringCloud Config通过github获取配置信息:
3344就是Config Server,它是微服务的配置中心,是连接外部支持(git)和内层各个微服务的通道,当外部配置变化时,3344可以同步更新,同时各个微服务客户端可以从配置中心Config Server中获取修改的更新值。
① 新建cloud-config-center-3344模块,修改pom.xml,添加spring-cloud-config-server坐标:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId><!--Config服务端-->
</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>
② 编写yml文件:
server:
port: 3344
spring:
application:
name: cloud-config-center
cloud:
config:
server:
git:
uri: https://github.com/ghh1221/springcloud-config.git # github上面的仓库地址
search-paths:
- springcloud-config # 搜索目录
label: master # 读取分支
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
③ 编写主配置类:使用注解@EnableConfigServer
激活Config配置中心。
@SpringBootApplication
@EnableConfigServer
public class ConfigCenterMain3344 {
public static void main(String[] args) {
SpringApplication.run(ConfigCenterMain3344.class,args);
}
}
④ 进入C:\Windows\System32\drivers\etc文件下的host文件,增加映射:
127.0.0.1 config-3344.com
⑤ 测试:启动注册中心7001、启动3344
github中config-dev.yml文件内容:
测试3344是否可以从github上获取配置,实际是读取到配置文件中的GitHub的地址然后拼上/master/config-dev.yml
⑥ 配置文件的请求地址规则(3种方式):
-
P地址:端口号/label标签/application-profile;label:分支、name:服务名、profiles:环境(dev/test/prod)
-
省略了label标签,因为yml文件中已配置了,所以yaml文件配置label标签后,请求路径中可写也可不写。这里默认会读取master分支,因为我们配置文件中配置了,因为配置文件中设置了label:master
访问:http://localhost:3344/master/config-dev.yml -
就是和方式1逆序:
3. SpringCloud Config客户端3355
SpringCloud Config从配置中心3344获取更新值:
① 新建cloud-config-client-3355模块,修改pom.xml,添加spring-cloud-starter-config
坐标。
<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-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>
② 编写yml配置文件:
bootstrape.yml文件的优先级高于application.yml的优先级
这个配置文件的作用是先到3344Config配置中心加载配置,然后加载到自己的application.yml中
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/fongig-dev.yml)
uri: http://localhost:3344 # 配置中心地址
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka
③编写主配置类:
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain3355 {
public static void main(String[] args) {
SpringApplication.run(ConfigClientMain3355.class,args);
}
}
④ 业务类:将配置信息以REST接口形式暴露
package com.atguigu.springcloud.controller;
@RestController
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo(){
return configInfo;
}
}
⑤ 测试:如果客户端运行正常,就会读取到github上配置文件的config.info下的配置
访问:http://localhost:3355/configInfo,这个结果就是通过3344服务端配置中心间接从git仓库获取的
客户端出现的问题:上面3355确实获取到了github中的配置文件,但是如果此时配置文件修改了,3355是获取不到的,3344可以实时获取到最新配置文件,但是3355却获取不到,除非重启服务。
4. 实现动态刷新(3355不需要重启服务)
① 在3355的pom文件中添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
② 在yml文件中暴露监控端口:
# 暴露监控端口
management:
endpoints:
web:
exposure:
include: "*"
③ 修改controller,添加注解@RefreshScope刷新:
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo(){
return configInfo;
}
}
④ 重启服务:
先将github中config-dev.yml文件中的version改为9,即配置文件修改了,然后通过3344获取github文件的内容:
此时3355还不可以动态获取:
因为此时还需要外部发送post请求通知3355,使用postman发送post请求:http://localhost:3355/actuator/refresh
此时不重启3355,同样可以得到修改后的配置文件:
具体流程就是:我们启动好服务后,运维人员修改了配置文件,然后发送一个post请求通知3355,3355就可以获取最新配置文件。
问题:
如果有多个客户端怎么办(3355,3356,3357…)
虽然可以使用shell脚本,循环刷新,但是可不可以使用广播一次通知??
这些springconfig做不到,需要使用springcloud Bus消息总线