Config
Table of Contents generated with DocToc (opens new window)
# Config
# 概述
# 分布式系统面临的配置问题
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。
SpringCloud提供了ConfigServer来解决这个问题
# 是什么
SpringCloud Config为微服务架构中的微服务提供集中式的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
SpringCloud Config分为服务端和客户端两部分。
服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口
客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置。服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容
# 能干嘛
- 集中管理配置文件
- 不同环境不同配置,动态化的配置更新,分环境部署,比如dev/test/prod/beta/release
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
- 当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置
- 将配置信息以REST接口的形式暴露
# Config服务端配置与测试
# 新建仓库
- 在Gitee新建springcloud-config的仓库
目录结构如下
文件内容:
然后新建cloud-config-center3344模块,它即为Cloud的配置中心模块
# pom
<dependencies>
<!-- 通用的依赖-->
<dependency>
<groupId>com.zdk</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</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.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
新增
spring-cloud-config-server
的依赖即可,其他与前面的一致
# yaml
server:
port: 3344
# 服务名称 (必写)
spring:
application:
name: cloud-config-center
cloud:
config:
server:
git:
uri: https://gitee.com/hnistzdk/springcloud-config.git #GitHub仓库名称
## (额外)搜索目录 经测试 默认会读取根目录下的文件
## 但如果要读取根目录文件夹中的文件 就必须添加search-paths 否则读取不到
search-paths:
- config-files
## 读取分支(要读的远程仓库的)
label: master
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 主启动类
package com.zdk.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.config.server.EnableConfigServer;
/**
* @Description
* @Author zdk
* @Date 2022/11/12 17:30
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class ConfigCenterMain3344 {
public static void main(String[] args) {
SpringApplication.run(ConfigCenterMain3344.class, args);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 修改hosts文件
新增以下映射
127.0.0.1 config-3344.com
# 简单测试
访问http://config-3344.com:3344/master/config-dev.yaml(最后这个是文件名)
# 踩坑
# uri问题
不要使用GitHub仓库,很难连接上;使用Gitee仓库,建议用https,且仓库为public,否则会需要认证
# label
label必须是你要读取的仓库的一个存在的分支,如果是不存在的分支而去访问,会404,
比如http://config-3344.com:3344/master22/config-dev.yaml就会404
# search-paths
(额外)搜索目录 经测试 默认会读取根目录下的文件 但如果要读取根目录的文件夹中的文件 就必须添加search-paths 否则读取不到
# 配置文件命名必须符合指定的规范
官网指定的访问规则有五种
- /{label}/{application}-{profile}.yaml
- /{application}-{profile}.yaml
- /{application}-{profile}/{label}
- /{label}/{application}-{profile}.properties
- /{application}-{profile}.properties
所以文件必须是xxx-xxx.yaml
这种格式的命名才行,否则访问不到(经测试)
# Config客户端配置与测试
新建cloud-config-center3355模块
# pom
将上面的server的pom中的config-server依赖替换为以下依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
2
3
4
# bootstrap.yaml
# 是什么
applicaiton.yaml
是用户级的资源配置项
bootstrap.yaml
是系统级的,优先级更加高
Spring Cloud会创建一个
BootstrapContext
,作为Spring应用的Application Context
的父上下文。初始化的时候,BootstrapContext
负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的Environment
。 `
Bootstrap
属性有高优先级,默认情况下,它们不会被本地配置覆盖。Bootstrap context
和Application Context
有着不同的约定,所以新增了一个bootstrap.yaml
文件,保证Bootstrap Context
和Application Context
配置的分离。
要将Client模块下的
application.yaml
文件改为bootstrap.yaml
,这是很关键的 因为bootstrap.yaml
是比application.yaml
先加载的。bootstrap.yaml
优先级高于application.yaml
# 内容
server:
port: 3355
# 服务名称 (必写)
spring:
application:
name: cloud-config-client
cloud:
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀mingc
# 以上3个配置结合即可读取到唯一指定的一个配置
uri: http://config-3344.com:3344/ #配置中心地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 启动类
package com.zdk.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @Description
* @Author zdk
* @Date 2022/11/12 18:51
*/
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigClientMain3355{
public static void main(String[] args){
SpringApplication.run(ConfigClientMain3355.class,args);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 业务类
@RestController
public class ConfigClientController {
@Value("${server.name}")
private String serverName;
@GetMapping("/configInfo")
public String getConfigInfo(){
return serverName;
}
}
2
3
4
5
6
7
8
9
10
# 启动
这里启动发生异常
Description: No spring.config.import property has been defined
1
2
3SpringCloud 2020.* 版本把bootstrap禁用了,导致在读取文件的时候读取不到而报错,所以我们只要把bootstrap从新导入进来就会生效了。
<!-- 解决No spring.config.import property has been defined报错--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>
1
2
3
4
5
# 测试
# Config客户端之动态刷新
在我们修改配置文件后,客户端在必须重启才能获取到修改的新值,如果有多个客户端的话就会变得十分麻烦,所以有了动态刷新机制
# 修改pom
如果没有actuator监控依赖,需要添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2
3
4
# 修改yaml,暴露监控端口
在客户端的bootstrap.yaml中添加如下配置
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
2
3
4
5
6
# 业务类
在Controller上增加
@RefreshScope
注解
# 测试
此时修改git进行测试,发现在3355中依旧还是没有获取到最新的修改
这里其实需要手动发送给actuator一个post请求,来告诉3355刷新(重新从3344配置中心拉取配置信息),就能获取到最新的了
curl -X POST "http://localhost:3355/actuator/refresh"
进行测试,这样3355就拿到了最新的配置