15.conifg(服务配置)
微服务意味着将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务
由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的
springcloud 提供了ConifgServer来解决这个问题,我们每个微服务都自己带着一个application.yml,上百个配置文件的管理..
springboot config分为服务端和客户端两部分
服务端也成为分布式配置中心,他是一个独立的微服务应用,用来连接配置服务器并未客户端提供获取配置信息,加密/解密信息等访问接口
客户端则是通过指定给的配置中心来管理应用资源,以及与业务线管的配置内容,并在启动的时候从配置中心获取或加载配置信息配置服务器
默认采用git来存储配置信息,这样有利于对环境配置进行版本管理,并且通过git客户端工具快来方便的管理和访问配置内容
功能:
1.集中管理配置文件
2.不同环境不同配置,动态的配置更新,分环境部署,比如dev/test/prod/beta/release
3.运行期间动态调整配置,不在需要在每个服务部署的机器上编辑配置文件,服务回想配置中心统一拉取自己的配置信息
4.当配置发生变化时,服务不需要重启即可感知到配置的变化并应用新的配置
5.将配置信息以REST接口的形式暴露
1.springcloud config服务端的搭建
首先:这个配置文件起名字也是有讲究的,
一共支持以下几种方式:
1./{application}/{profile}[/{label}]
2./{application}-{profile}.yml
3./{label}/{application}-{profile}.yml
4./{application}-{profile}.properties
5./{label}/{application}-{profile}.properties
label 分支名称 如:master dev ,不写就是master。
application 配置文件名称(client-test 后面我们在写config client服务的时候,项目名就是取 client-test)
profiles 环境名称,不可省略,假如我们的仓库中配置文件命名没有环境名称,可以profile可以写为-a (dev)
此处的逻辑是,服务端从gitee上去获取配置文件
服务端的搭建代码:
1.pom文件:
<dependencies>
重点:引入springcloud 的config server包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</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.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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.cn.wmd.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2.application.yml
server:
port: 3355
spring:
application:
name: cloud-config
#重点1:远程git仓库的配置
cloud:
config:
server:
git:
#重点2:寻找的仓库名称
search-paths: 吴孟达/spring-clooud
#重点3:地址-->即代码的克隆地址
uri: https://gitee.com/wu-mengda/spring-clooud.git
#寻找的分支,如果仓库不是公开仓库,则需要配置用户名和密码!
default-label: master
#重点2:eureka的相关配置
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#单机版
defaultZone: http://eureka7001:7001/eureka,http://eureka7002:7002/eureka
instance:
instance-id: cloud-config
prefer-ip-address: true
# Eureka客户端向服务心跳的时间间隔是1s,默认是30秒
lease-renewal-interval-in-seconds: 1
3.启动类代码:
@SpringBootApplication
//config的配置标签
@EnableConfigServer
//eureka的配置标签
@EnableEurekaClient
public class ConfigApplication3355 {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication3355.class, args);
}
}
4.测试:因为config服务端会以REST风格将配置文件暴露出来,所以可以通过浏览器进行访问!
这时候浏览器输入:http://localhost:3355/config-prod.yml
可以获取到配置文件的内容
config:
info: master brach,spring-cloud/config-prod.yml version=1
2.bootstrap.yml
application.yml是用户级别的配置项
bootstrap.yml是系统级别的,优先级别更高
springcloud会创建一个"Bootstrap Context",作为Spring应用的Application Context的父上下文。初始化的时候,BootStrap Context负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的Environment
BootStrap属性具有更高的优先级,他们不会被本地配置覆盖。'bootstrap context'和'application context'有着不同的约定,随意新增一个'bootstrap.yml'文件,保证bootstrap Context和application context配置的分离
bootstrp.yml是比application.yml先加载的。bootstrap.yml优先级高于applicaiton.yml
3.config的客户端
1.pom文件代码:
<dependencies>
<!--重点1:config 客户端jar-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</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.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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.cn.wmd.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
2.重点2:新建一个bootstrap.yml(注意这里是bootstrap.yml,因为bootstrap.yml是系统配置,优先加载)
server:
port: 3344
spring:
application:
name: cloud-config-client
#重点1:springcloud config的配置
cloud:
#config客户端配置
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述三个综合:master分支上的config-dev.yml配置文件被读取
#加上路径uri后:http://localhost:3355/master/config-dev.yml
uri: http://localhost:3355 #config服务端的地址
#重点2:eureka的配置
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#单机版
defaultZone: http://eureka7001:7001/eureka,http://eureka7002:7002/eureka
instance:
instance-id: cloud-config-client
prefer-ip-address: true
3.启动类的代码:
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication.class, args);
}
}
4.控制层代码:
@RestController
public class ConfigController {
/*
如果可以打印出configinfo的内容,则说明,配置加载成功!
*/
@Value("${config.info}")
private String configInfo;
@GetMapping("/getConfigInfo")
public String getConfigInfo(){
return configInfo;
}
}
5.测试:
访问客户端:http://localhost:3344/getConfigInfo
返回:master brach,spring-cloud/config-dev.yml version=1
config-dev.yml的真是内容:
config:
info: "master brach,spring-cloud/config-dev.yml version=1"
发现一致,说明配置文件加载成功!
4.分布式配置的动态刷新问题
1.当gitee上更改了config.dev配置文件的内容:更该version=2
config:
info: "master brach,spring-cloud/config-dev.yml version=2"
2.config服务端访问:http://localhost:3355/master/config-dev.yml
config:
info: master brach,spring-cloud/config-dev.yml version=2
3.但是config客户端访问:http://localhost:3344/getConfigInfo:输出的version=1,即配置并没有动态刷新到config客户端(重启客户端可生效)
master brach,spring-cloud/config-dev.yml version=1
问题:上述客户端无法动态刷新(必须重启)问题如何解决?
解决:config客户端的动态刷新问题
1.在config客户端pon中必须引入:监控的包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.在bootstrap.yml中配置添加
#暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
3.在控制层获取配置的地方加上标签@RefreshScope(自动刷新)
@RestController
@RefreshScope
public class ConfigController {
/*
如果可以打印出configinfo的内容,则说明,配置加载成功!
*/
@Value("${config.info}")
private String configInfo;
@GetMapping("/getConfigInfo")
public String getConfigInfo(){
return configInfo;
}
}
4.重要:必须向客户端发送一个post请求:curl -X POST "http://localhost:3344/actuator/refresh"
cmd窗口下执行上述命令
5.这时访问客户端:http://localhost:3344/getConfigInfo
master brach,spring-cloud/config-dev.yml version=2
总结:
如果要达到动态刷新的效果
1.改pom,加actuator的包
2.改配置文件bootstrap.yml,加上监控断点配置
3.加上自动刷新标签@RefreshScope(在引用处)
4.重要(不可缺),必须向config客户端发送一个POST请求:http://localhost:3344/actuator/refresh
5.这样项目不需要重启也可以动态加载配置文件