博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringCloud学习笔记(七)----配置中心Config、消息总线Bus
阅读量:3940 次
发布时间:2019-05-24

本文共 12572 字,大约阅读时间需要 41 分钟。

SpringCloud config分布式配置中心

概述

分布式系统面临的配置问题:

微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。

通俗来说,每个微服务都需要一个配置文件,如果有几个微服务都需要连接数据库,那么就需要配4次数据库相关配置,并且当数据库发生改动,那么需要同时修改4个微服务的配置文件才可以。

所以有了SpringCloud Config配置中心来统一管理微服务中相同配置文件。

config是什么?

SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。

在这里插入图片描述
SpringCloud Config分为服务端和客户端两部分。

服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。

客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器,默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。

Config 能干嘛?

  1. 集中管理配置文件
  2. 不同环境不同配置,动态化的配置更新,分环境部署比如dev/test/prod/beta/release
  3. 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息。
  4. 当配置发生变动时,服务不再需要重启即可感知到配置的变化并应用新的配置。
  5. 将配置信息以REST接口的形式暴露

SpringCloud Config默认使用Git来存储配置文件(也有其它方式,比如支持svn和本地文件,但最推荐的还是Git,而且使用的是http/https访问的形式)

Config服务端配置与测试

使用Github作为配置中心的仓库

初始化git环境

1.在Github上新建一个名为springcloud-config的新Repository

2.获取新建的git地址

git@github.com:xiaoxinxin718/springcloud-config.git

3.本地硬盘上新建git仓库并clone

git clone 上面获取的git地址

进行clone的时候,报如下错误:

在这里插入图片描述
本地git bash 使用git clone git@github.com:***.git方式下载github代码至本地时需要依赖ssh key,遇到权限不足问题时一般都是SSH key失效或者SSH key不存在,重新创建SSH key一般就可以解决问题; 可以参照下面这篇博客

解决之后,在进行clone,本地仓库已有从GitHub上下载下来的文件。

在这里插入图片描述
在这里插入图片描述

新建config模块

1.新建Module模块cloud-config-center-3344它为Cloud的配置中心模块cloudConfig Center

2.POM.xml

org.springframework.cloud
spring-cloud-config-server
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
com.atguigu.springcloud
cloud-api-commons
${
project.version}
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test

3.application.yml

server:  port: 3344spring:  application:    name: cloud-config-center  cloud:    config:      server:        git:          uri:  填写你自己的github路径          search-paths:            - springcloud-config      label: mastereureka:  client:    service-url:      defaultZone:  http://localhost:7001/eureka

4.主启动类

@SpringBootApplication@EnableConfigServerpublic class ConfigCenterMain3344 {
public static void main(String[] args) {
SpringApplication.run(ConfigCenterMain3344 .class,args); }}

测试通过Config微服务是否可以从Github上获取配置内容。

访问http://localhost:3344/master/config-dev.yml,发现报如下错误:

在这里插入图片描述
上网百度了一大堆解决办法,经过一一尝试,将配置文件修改如下:

server:  port: 3344spring:  application:    name: cloud-config-center  cloud:    config:      server:        git:          uri: https://github.com/xiaoxinxin718/springcloud-config.git          #git@github.com:xiaoxinxin718/springcloud-config.git          search-paths:            - springcloud-config          username: github账号          password: github密码          skip-ssl-validation: true        default-label: mastereureka:  client:    service-url:      defaultZone:  http://localhost:7001/eureka

这样配置解决上面哪个错误,但是又出现了一个新的错误。

在这里插入图片描述
默认的label为master
Github现在master改为main, 修改 default-label 属性, 否则读不到

default-label: main

在测试,已成功实现用SpringCloud config 通过GitHub获取配置信息。

在这里插入图片描述

在这里插入图片描述

配置读取规则

在这里插入图片描述

1./{label}/{application}-{profile}.yml(最推荐使用这种方式)

label:分支(brance) name:服务名 profiles:环境(dev/test/prod)

main分支

  • http://localhost:3344/main/config-dev.yml
  • http://localhost:3344/main/config-test.yml
  • http://localhost:3344/main/config-prod.yml

dev分支

  • http://localhost:3344/dev/config-dev.yml
  • http://localhost:3344/dev/config-test.yml
  • http://localhost:3344/dev/config-prod.yml

2./{application}-{profile}.yml

  • http://localhost:3344/config-dev.yml
  • http://localhost:3344/config-test.yml
  • http://localhost:3344/config-prod.yml
  • http://localhost:3344/config-xxxx.yml(不存在的配置)
  • 如果访问不存在的配置,会返回一个空{},并不会报错。
  • 默认读取main分支,因为我们配置文件配置了。

3./{application}-{profile}[/{label}]

  • http://localhost:3344/config/dev/master
  • http://localhost:3344/config/test/master
  • http://localhost:3344/config/prod/master
  • 这个方法读取的配置是JSON格式的。

Config客户端配置与测试

1.新建cloud-config-client-3355

2.POM.xml

org.springframework.cloud
spring-cloud-starter-config
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
com.atguigu.springcloud
cloud-api-commons
${
project.version}
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test

3.bootstrap.yml

这个配置文件的作用是,先到配置中心加载配置,然后加载到application.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"配置的分离。

要将Client模块下的application.yml文件改为bootstrap.yml,这是很关键的。

因为bootstrap.yml是比application.yml先加载的。bootstarp.yml优先级高于application.yml。

server:  port: 3355spring:  application:    name: config-client  cloud:    #Config客户端配置    config:      #这四个整合在一起的意思是:客户端会读取http://localhost3344/main/config-dev.yml上面的配置文件      label: main #分支名称      name: config #配置文件名称      profile: dev #读取后缀名称,      uri: http://localhost:3344 #配置中心地址keureka:  client:    service-url:      defaultZone: http://eureka7001.com:7001/eureka

4.主启动类

@SpringBootApplication@EnableEurekaClientpublic class ConfigClientMain3355 {
public static void main(String[] args) {
SpringApplication.run( ConfigClientMain3355.class,args); }}

5.controller类

前面所提到的,以rest风格将配置对外暴露。

@RestControllerpublic class ConfigClientController {
@Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo(){
return configInfo; }}

6.测试:

启动3344、3355,访问 http://localhost:3355/configInfo。成功实现了客户端3355访问SpringCloud Config3344通过GitHub获取配置信息

在这里插入图片描述

7.问题:
上面3355确认获取到了配置文件,但是如果此时配置文件修改了,3355是获取不到的,3344可以实时获取到最新配置文件,除非3355重启服务。

Config客户端之动态刷新

1.修改3355,添加一个pom依赖

org.springframework.boot
spring-boot-starter-actuator

2.修改配置文件,添加一个配置:

暴露监控端口。

management:  endpoints:    web:      exposure:        include: "*"

3.修改controller,添加@RefreshScope

@RestController@RefreshScopepublic class ConfigClientController {
@Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo(){
return configInfo; }}

4.重启3355

此时3355还不可以动态获取。 还需要外部发生post请求通知3355。
在这里插入图片描述
此时在刷新3355,发现可以获取到最新的配置文件了,这就实现了动态获取配置文件,因为3355并没有重启。

具体流程就是:

  • 启动好服务之后
  • 运维人员,修改了配置文件,然后发送一个post请求通知3355
  • 3355就可以获取最新配置文件。

问题:

如果有多个客户端怎么办(3355,3356,3357…),虽然可以使用shell脚本,循环刷新。

但是可不可以使用广播,一次通知?

我们可以使用SpringCloud Bus配合SpringCloud Config实现。

消息总线SpringCloud Bus

概述

Spring Cloud Bus配合Spring Cloud Config 使用可以实现配置的动态刷新。

在这里插入图片描述
Spring Cloud Bus 能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道。

在这里插入图片描述

注意,这里两张图片,就代表两种广播方式:

  • 图1:它是Bus直接通知给其中一个客户端,由这个客户端开始蔓延,传播给其他所有客户端。
  • 图2:它是通知给配置中心的服务端,由服务端广播给所有客户端。

为什么被称为总线

在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。

基本原理:

ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。

简单来说:

就是通过消息队列达到广播的效果,我们要广播每个消息时,主要放到某个topic中,所有监听的节点都可以获取到。

RabbitMQ环境配置

安装过程可以看我以前写的在Linux下安装RabbitMQ博客。

SpringCloud Bus动态刷新全局广播

为了演示广播效果,根据3355在创建一个cloud-config-client-3366模块。

Bus广播有两种形式:

  • 利用消息总线触发一个客户端/bus/refresh,而刷新所有客户端的配置。
  • 利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端的配置(更加推荐)

方法一有如下缺点:

  • 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新职责
  • 破坏了微服务各节点的对等性
  • 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改

所以选择方法二的架构。

给cloud-config-center-3344配置中心服务端添加消息总线支持

1.在POM.xml添加如下依赖

org.springframework.cloud
spring-cloud-starter-bus-amqp
org.springframework.boot
spring-boot-starter-actuator

2.修改配置文件

server:  port: 3344spring:  application:    name: cloud-config-center  cloud:    config:      server:        git:          uri: https://github.com/xiaoxinxin718/springcloud-config.git          #git@github.com:xiaoxinxin718/springcloud-config.git          search-paths:            - springcloud-config          username: xiaoxinxin718          password: 1424025155abc          skip-ssl-validation: true        default-label: main  #rabbitmq相关配置  15672是web管理界面的端口,5672是MQ访问的端口  rabbitmq:    host: 172.16.114.135    port: 5672    username: guest    password: guesteureka:  client:    service-url:      defaultZone:  http://localhost:7001/eureka#rabbitmq相关配置,暴露bus刷新配置的端点management:  endpoints: #暴露bus刷新配置的端点    web:      exposure:        include: 'bus-refresh'

给cloud-config-center-3355客户端添加消息总线支持

1.在POM.xml添加如下依赖

org.springframework.cloud
spring-cloud-starter-bus-amqp
org.springframework.boot
spring-boot-starter-actuator

2.修改配置文件

server:  port: 3355spring:  application:    name: config-client  cloud:    #Config客户端配置    config:      #这四个整合在一起的意思是:客户端会读取http://localhost3344/main/config-dev.yml上面的配置文件      label: main #分支名称      name: config #配置文件名称      profile: dev #读取后缀名称,      uri: http://localhost:3344 #配置中心地址k  #rabbitmq相关配置  15672是web管理界面的端口,5672是MQ访问的端口  rabbitmq:    host: 172.16.114.135    port: 5672    username: guest    password: guesteureka:  client:    service-url:      defaultZone: http://eureka7001.com:7001/eurekamanagement:  endpoints:    web:      exposure:        include: "*"

给cloud-config-center-3366客户端添加消息总线支持

1.在POM.xml添加如下依赖

org.springframework.cloud
spring-cloud-starter-bus-amqp
org.springframework.boot
spring-boot-starter-actuator

2.修改配置文件

server:  port: 3366spring:  application:    name: config-client  cloud:    config:      label: main      name: config      profile: dev      uri: http://localhost:3344  #rabbitmq相关配置  15672是web管理界面的端口,5672是MQ访问的端口  rabbitmq:    host: 172.16.114.135    port: 5672    username: guest    password: guesteureka:  client:    service-url:      defaultZone: http://eureka7001.com:7001/eurekamanagement:  endpoints:    web:      exposure:        include: "*"

测试:启动7001、3344、3355、3366

此时修改GitHub上的配置文件
此时只需要刷新3344,即可让3355、3366动态获取最新的配置文件。

curl -X POST "http://localhost:3344/actuator/bus-refresh"

一次修改,广播通知,处处生效。

其原理就是:

ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。

总结:

所有客户端都监听了一个rabbitMq的topic,我们将信息放入这个topic,所有客户端都可以送到,从而实时更新。

SpringCloud Bus动态刷新定点通知

不想全部通知,只想定点通知。比如只通知3355,不通知3366。

公式:http://localhost:配置中心的端口号/actuator/bus-refresh/{destination}

/bus/refresh请求不再发送到具体的服务实例上,而是发给config server并通过destination参数类指定需要更新配置的服务或实例

这里只通知3355:

curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"

在这里插入图片描述

在这里插入图片描述
可以发现,实际上就是通过微服务的名称+端口号进行指定。

转载地址:http://lpiwi.baihongyu.com/

你可能感兴趣的文章
syslog 和 rsyslog
查看>>
Linux下,write/read,recv/send, recvfrom/sendto的区别
查看>>
ubuntu下 rc.local的脚本不运行
查看>>
Linux下简单Makefile文件的编写
查看>>
linux下配置JDK JAVA环境
查看>>
解决Ubuntu 14.04 grub选择启动项10秒等待时间
查看>>
Python函数操作集锦之字符串测试、判断函数
查看>>
Python字符串操作集锦之字符串映射表
查看>>
Python字符串操作集锦之字符串编码解码函数
查看>>
Python字符串类型转换函数
查看>>
Python有用的命令
查看>>
Python条件语句
查看>>
Python eval()函数
查看>>
Linux rz和sz命令详解
查看>>
Python 集合set
查看>>
Codeforces Round #400 (Div. 1 + Div. 2, combined)D - The Door Problem(2-sat)
查看>>
IDEA中Struts2文件上传时404错误The origin server did not find a current representation for the target resour
查看>>
Perl/Tk 变量追踪及类线程实现
查看>>
1.嵌入式开发环境搭建--虚拟机安装(unbutu)系统
查看>>
2.嵌入式开发环境搭建--(unbutu)系统
查看>>