Spring Cloud 入门 ---- Config 配置中心【随笔】
配置中心
Spring Cloud 入门 ---- Config 配置中心
介绍
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的微服务,由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。Spring Cloud 提供了 ConfigServer 来解决这个问题。
官网:https://docs.spring.io/spring-cloud-config/docs/2.2.5.RELEASE/reference/html/
是什么
Spring Cloud Config 为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为
各个不同微服务应用
的所有环境提供一个中心化的外部配置
。
怎么用
Spring Cloud Config 分为
服务端
和客户端
两部分。服务端也称为
分布式配置中心,它是一个独立的微服务应用
,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息,配置服务器默认采用 git 来存储配置信息,这样就有助于对环境配置的版本进行管理,并可以通过 git 客户端工具来方便的管理和访问配置内容。
图解:
能干嘛
- 集中管理配置文件
- 不同环境不同配置,动态化的配置更新,分环境部署;比如:dev/test/prod/beta/release
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
- 当配置发生变动时,服务不需要重启即可感知到配置的变化,并应用新的配置
- 将配置信息以 REST 接口的形式暴露
Config 配置总控中心搭建
创建配置仓库
一、在 github 上创建配置仓库(springcloud-config),并新建几个配置文件
内容如下:以下为演示内容,实际工作中按需要配置。
config-dev.yml
config:
info: "master branch,springcloud-config/config-dev.yml version=1"
config-prod.yml
config:
info: "master branch,springcloud-config/config-prod.yml version=1"
config-test.yml
config:
info: "master branch,springcloud-config/config-test.yml version=1"
二、将配置中心内容拉取到本地项目下
创建配置中心模块
导入 pom 依赖
<!--配置中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- 引入 eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
添加 yml 配置文件
server:
port: 3344
spring:
application:
name: config-center-service
security:
# 配置spring security登录用户名和密码
user:
name: akieay
password: 1qaz2wsx
cloud:
config:
server:
git:
force-pull: true
uri: https://github.com/admin-strat/springcloud-config.git #github上面的git仓库
username: xxxxxxx
password: xxxxxxxx
# 搜索目录
search-paths:
- springcloud-config
# 读取分支
label: master
eureka:
client:
#表示是否将自己注册进 Eureka Server服务 默认为true
register-with-eureka: true
#f是否从Eureka Server抓取已有的注册信息,默认是true。单点无所谓,集群必需设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url: # 设置与 Eureka Server 交互的地址 查询服务与注册服务都需要这个地址
# defaultZone: http://localhost:7001/eureka
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@eureka7001.com:7001/eureka,http://${spring.security.user.name}:${spring.security.user.password}@eureka7002.com:7002/eureka
instance:
instance-id: config-center-3344
## 当调用getHostname获取实例的hostname时,返回ip而不是host名
prefer-ip-address: true
# Eureka客户端向服务端发送心跳的时间间隔,单位秒(默认30秒)
lease-renewal-interval-in-seconds: 10
# Eureka服务端在收到最后一次心跳后的等待时间上限,单位秒(默认90秒)
lease-expiration-duration-in-seconds: 30
主启动
@EnableConfigServer
开启基于注解的配置中心功能
@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class ConfigCenterApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigCenterApplication.class, args);
}
}
启动服务,访问:http://localhost:3344/master/config-dev.yml 如果能够得到配置中心对应的信息,则服务创建成功。
以上我们成功的从配置中心读取到了
master
分支下的config-dev.yml
配置文件;关于配置文件的读取规则将在下面介绍。
配置的读取规则
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
label:分支;application:服务名;profile:环境(dev/test/prod)
这里我们重点介绍前面三种:
/{application}/{profile}[/{label}],例如:http://localhost:3344/config/dev/master 可以看到得到的信息将是一个包含配置信息的 json 串。
/{application}-{profile}.yml,例如:http://localhost:3344/config-dev.yml 可以看到由于没有指定分支,将访问默认的 master 分支下的 config-dev.yml 配置文件,并直接返回配置文件的信息。
/{label}/{application}-{profile}.yml,例如:http://localhost:3344/master/config-dev.yml ,这种我们前面测试过,将返回我们指定的 master 分支【也可以指定其它分支】下的 config-dev.yml 配置文件的信息。
测试了实际存在的文件,接下来我们测试个在 github 中不存在的文件,例如:http://localhost:3344/master/abcdef-dev.yml 可以看到当我们访问的配置文件不存在时,将返回一个空的对象。
以上就是常用的几种配置读取规则的介绍,个人推荐使用第三种:/{label}/{application}-{profile}.yml
Config 客户端配置与测试
创建客户端模块
导入 pom 依赖
<!--config-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- 引入 eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
创建 bootstrap.yml
application.yml 是用户级的资源配置项;bootstrap.yml 是系统级的,
优先级更高
Spring Cloud 会创建一个
Bootstrap Context
,作为 Spring 应用的Application Context
的父上下文
。初始化的时候Bootstrap Context
负责从外部加载配置属性并解析配置。这两个上下文共享一个外部获取的Environment
。
Bootstrap
属性有更高优先级,默认情况下,它们不会被本地配置覆盖。Bootstrap context
和Application context
有着不同的约定,所以新增一个Bootstrap.yml
文件,保证Bootstrap context
和Application context
配置的分离。
要将 Client 模块下的 application.yml 文件改为 bootstrap.yml,这是很关键的,
因为 bootstrap.yml 是比 application.yml 先加载的。bootstrap.yml 优先级高于 application.yml。
server:
port: 3355
spring:
application:
name: config-client-service
security:
# 配置spring security登录用户名和密码
user:
name: akieay
password: 1qaz2wsx
cloud:
config:
uri: http://localhost:3344 #配置中心地址
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取
eureka:
client:
#表示是否将自己注册进 Eureka Server服务 默认为true
register-with-eureka: true
#f是否从Eureka Server抓取已有的注册信息,默认是true。单点无所谓,集群必需设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url: # 设置与 Eureka Server 交互的地址 查询服务与注册服务都需要这个地址
# defaultZone: http://localhost:7001/eureka
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@eureka7001.com:7001/eureka,http://${spring.security.user.name}:${spring.security.user.password}@eureka7002.com:7002/eureka
instance:
instance-id: config-client-3355
## 当调用getHostname获取实例的hostname时,返回ip而不是host名
prefer-ip-address: true
# Eureka客户端向服务端发送心跳的时间间隔,单位秒(默认30秒)
lease-renewal-interval-in-seconds: 10
# Eureka服务端在收到最后一次心跳后的等待时间上限,单位秒(默认90秒)
lease-expiration-duration-in-seconds: 30
启动类
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication.class, args);
}
}
业务类
@RestController
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo(){
return configInfo;
}
}
启动服务,访问:http://localhost:3355/configInfo 可以看到通过 bootstrap.yml 指定的配置文件,我们读取到了配置中心中配置文件的信息。
修改 profile 为 test ,重启服务并访问:http://localhost:3355/configInfo 如图:可以看到我们读取到了配置中心 test 环境的配置文件信息。
分布式配置的动态刷新问题
config 配置中心 与 config 客户端启动好后,既可以测试是否能读取 github 上的配置。随之而来的一个问题是:当修改并提交 githup 上的配置信息时,3344 配置中心可以实现自动更新;但是 3355 客户端始终是原来的配置,配置信息没有更新;需要 3355 重启或者重新加载,配置信息才会更新。下面我们将验证这种情况:
一、将环境改回 dev 环境,并访问:http://localhost:3344/master/config-dev.yml 与 http://localhost:3355/configInfo 可以看到读取到的配置中心信息是一致的。
二、修改 github 上 config-dev.yml 的配置信息,修改如下,并访问:http://localhost:3344/master/config-dev.yml 与 http://localhost:3355/configInfo 可以看到 3344配置中心的信息更新了,而 3355 客户端信息还是原来的。
config:
info: "master branch,springcloud-config/config-dev.yml version=2 update config info"
三、重启 3355 客户端,并访问:http://localhost:3344/master/config-dev.yml 与 http://localhost:3355/configInfo 这时可以看到 3344 与 3355 读取到的都是更新后的信息。
通过以上的案例我们证实了 修改 github 上配置信息时,配置中心的信息会实时更新,而客户端信息则不会;需要重启服务才会更新,而重启这种方法明显是不合理的,在生产环境中我们总不能改下配置就重启下服务。在下面我们将介绍具体的解决方案。
Config 动态刷新之手动版
pom 中引入 actuator 监控,若已引入则跳过该步骤
<!--监控管理-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
修改 bootstrap.yml ,暴露监控端口号(客户端):
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: 'refresh'
业务类Controller 中添加注解 @RefreshScope
@RestController
@RefreshScope
public class ConfigClientController {
重新启动客户端,此时修改 github 上配置信息,config 配置中心会自动更新配置信息,客户端需要发送一个:"http://localhost:3355/actuator/refresh 请求,即可更新配置信息。下面我我们将来验证:
一、修改 github 上 config-dev.yml 配置信息,如下:
config:
info: "master branch,springcloud-config/config-dev.yml version=4 test config 手动刷新配置信息"
二、访问:http://localhost:3344/master/config-dev.yml 与 http://localhost:3355/configInfo 可以看到 3344 配置中心信息已经更新【虽然产生了中文乱码问题】,3355 依然是之前的配置信息。
三、使用postman 发送一个 post 请求:http://localhost:3355/actuator/refresh ,然后再访问:http://localhost:3355/configInfo 可以发现 3355 的配置信息也已经更新成功。
通过如上实验可知,当更新 github 上的配置文件信息后,我们可以通过发送 post 请求刷新客户端的配置信息;虽然还是有点麻烦,但是相对于重启服务已经算是一个比较能接受的了。但是新的问题随之而来:如果有多个微服务客户端,每个微服务都要执行一次post请求去手动刷新?是否可以广播,一次通知,处处生效?这些问题都将在下一节:Spring Cloud Bus 中解决
Config 配置中心添加安全认证
与 Eureka 类似,我们可以通过整合 SpringSecurity 来为配置中心添加安全认证。
修改 config 配置中心
添加 SpringSecurity pom 依赖
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
修改 yml 配置spring security登录用户名和密码;由于之前我们 Eureka Client 连接注册中心时添加了这个配置,所以这里不需要重复添加,当然我们也可以将之前 连接 Eureka Client 的用户名 密码配置修改为其它的自定义配置信息,如下:主要修改了 eureka 的 defaultZone 与 security
server:
port: 3344
eureka-connection:
name: akieay
password: 1qaz2wsx
spring:
security:
# 配置spring security登录用户名和密码
user:
name: akieay
password: configcenter
eureka:
client:
service-url: # 设置与 Eureka Server 交互的地址 查询服务与注册服务都需要这个地址
# defaultZone: http://localhost:7001/eureka
defaultZone: http://${eureka-connection.name}:${eureka-connection.password}@eureka7001.com:7001/eureka,http://${eureka-connection.name}:${eureka-connection.password}@eureka7002.com:7002/eureka
重启 配置中心模块,访问:http://localhost:3344/config-dev.yml 发现直接进入了登录界面,输入我们配置的用户名与密码才能访问配置文件信息。
修改 config 客户端模块
在 bootstrap.yml 文件中添加配置信息,配置 config配置中心连接的用户名与密码
spring:
application:
name: config-client-service
cloud:
config:
uri: http://localhost:3344 #配置中心地址
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取
username: akieay
password: configcenter
重启服务,服务能正常启动;访问:http://localhost:3355/configInfo ,发现能正常读取到配置信息,则证明我们 安全认证配置成功。
Config 配置中心集群搭建
在微服务架构中,所有的服务都从配置中心获取配置,配置中心一旦宕机,会发生很严重的问题,所以配置中心需要搭建集群来避免单机故障造成整个分布式系统出现问题,下面我们搭建一个双节点的配置中心集群来演示配置中心集群的搭建。
配置中心修改
修改配置中心的配置文件名称为
application-one.yml
,并复制一份为application-two.yml
并修改端口号为 3345。
server:
port: 3345
eureka:
client:
instance-id: config-center-3345
修改原来服务的启动配置,并 copy 该服务创建第二个服务节点。
启动这两个配置中心模块,登录 Eureka 注册中心,即可查看服务是否注册成功。
客户端修改
修改 bootstrap.yml 配置文件,添加从注册中心获取配置中心地址的配置。注意:service-id 即为配置中心注册到 Eureka 的服务别名。
spring:
application:
name: config-client-service
cloud:
config:
# uri: http://localhost:3344 #配置中心地址
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取
username: akieay
password: configcenter
discovery:
enabled: true
service-id: CONFIG-CENTER-SERVICE
重启 客户端模块,访问:http://localhost:3355/configInfo 可以看到能够正常获取到 github 上的配置信息。
关掉配置中心节点 3344 模拟配置中心节点突然挂掉的情况,修改 github 上的配置信息,并调用 http://localhost:3355/actuator/refresh 刷新客户端,访问:http://localhost:3355/configInfo 发现能够正常读取到修改后的配置信息,则证明我们的集群配置成功。
至此,关于 config 配置中心 的介绍完毕。
上一篇: JAVA面试题 (一)
下一篇: python: 从远程服务器下载日志程序
推荐阅读
-
SpringCloud之分布式配置中心Spring Cloud Config高可用配置实例代码
-
详解spring cloud config整合gitlab搭建分布式的配置中心
-
spring cloud config分布式配置中心的高可用问题
-
Spring Cloud微服务架构的构建:分布式配置中心(加密解密功能)
-
spring cloud config 配置中心快速实现过程解析
-
跟我学SpringCloud | 第六篇:Spring Cloud Config Github配置中心
-
Spring Cloud Config实现分布式配置中心
-
SpringCloud之分布式配置中心Spring Cloud Config高可用配置实例代码
-
Spring Cloud Config 配置中心实践过程中,你需要了解这些细节!
-
跟我学SpringCloud | 第七篇:Spring Cloud Config 配置中心高可用和refresh