【SpringCloud】 配置中心Config和消息总线Bus

一、概述

二、Config

三、Refresh

四、配置中心服务化

五、基于Webhook和消息总线的解决方案

一、概述

SpringCloud配置中心包括Config和Bus两个组成部分,只要这样,才能保证主动推送。

下面主要分为四个部分,

Config讲了基本的配置中心,但这样如果修改配置客户端在运行中是无法改变的。

Refresh讲了我们修改配置文件后可以向客户端发送一个POST请求,可以利用WebHook的方式。

配置中心服务化讲了我们把配置中心独立成一个服务(最好多挂几个)挂到Eureka

基于Webhook和消息总线的解决方案,让我们客户端可以实时的感知配置变化,从而做出改边。

我们先看Config,然后集成Bus来达到我们配置中心的目的。

二、Config

1.Config概述

当一个系统配置文件修改,我们需要重启系统,但是微服务状态下系统数量太多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config 组件中,分两个角色,一是config server,二是config client。

引入spring cloud config后,我们的外部配置文件就可以集中放置在一个git仓库里,再新建一个config server,用来管理所有的配置文件,维护的时候需要更改配置时,只需要在本地更改后,推送到远程仓库,所有的服务实例都可以通过config server来获取配置文件,这时每个服务实例就相当于配置服务的客户端config client,为了保证系统的稳定,配置服务端config server可以进行集群部署,即使某一个实例,因为某种原因不能提供服务,也还有其他的实例保证服务的继续进行。

2.示例

⑴server

①添加依赖

 


	
		org.springframework.cloud
		spring-cloud-config-server
	

②配置文件

server:
  port: 8001
spring:
  application:
    name: spring-cloud-config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/cGitHub123/Springcloud.git     # 配置git仓库的地址
          search-paths: config-repo                             # git仓库地址下的相对地址,可以配置多个,用,分割。
          username:                                              # git仓库的账号
          password:                                              # git仓库的密码

Spring Cloud Config也提供本地存储配置的方式。我们只需要设置属性spring.profiles.active=native,Config Server会默认从应用的src/main/resource目录下检索配置文件。也可以通过spring.cloud.config.server.native.searchLocations=file:E:/properties/属性来指定配置文件的位置。虽然Spring Cloud Config提供了这样的功能,但是为了支持更好的管理内容和版本控制的功能,还是推荐使用git的方式。

③启动类

 

@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigServerApplication.class, args);
	}
}

④测试

直接访问:http://localhost:8001/neo-config/dev

返回值:

 

{
    "name": "neo-config", 
    "profiles": [
        "dev"
    ], 
    "label": null, 
    "version": null, 
    "state": null, 
    "propertySources": [
        {
            "name": "https://github.com/cGitHub123/Springcloud.git/config-repo/neo-config-dev.properties", 
            "source": {
                "neo.hello": "hello im dev update"
            }
        }
    ]
}

上述的返回的信息包含了配置文件的位置、版本、配置文件的名称以及配置文件中的具体内容,说明server端已经成功获取了git仓库的配置信息。


如果直接查看配置文件中的配置信息可访问:http://localhost:8001/neo-config-dev.properties,返回:neo.hello: hello im dev

修改配置文件neo-config-dev.properties中配置信息为:neo.hello=hello im dev update,再次在浏览器访问http://localhost:8001/neo-config-dev.properties,返回:neo.hello: hello im dev update。说明server端会自动读取最新提交的内容

仓库中的配置文件会被转换成web接口,访问可以参照以下的规则:

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
以neo-config-dev.properties为例子,它的application是neo-config,profile是dev。client会根据填写的参数来选择读取对应的配置。

⑵Client端

①添加依赖

 


	
		org.springframework.cloud
		spring-cloud-starter-config
	
	
		org.springframework.boot
		spring-boot-starter-web
	
	
		org.springframework.boot
		spring-boot-starter-test
		test
	

②配置文件

需要配置两个配置文件,application.properties和bootstrap.properties

application.properties如下:

 

spring.application.name=spring-cloud-config-client
server.port=8002

bootstrap.properties如下:

 

 

 

spring.cloud.config.name=neo-config
spring.cloud.config.profile=dev
spring.cloud.config.uri=http://localhost:8001/
spring.cloud.config.label=master

spring.application.name:对应{application}部分
spring.cloud.config.profile:对应{profile}部分
spring.cloud.config.label:对应git的分支。如果配置中心使用的是本地存储,则该参数无用
spring.cloud.config.uri:配置中心的具体地址
spring.cloud.config.discovery.service-id:指定配置中心的service-id,便于扩展为高可用配置集群。
特别注意:上面这些与spring-cloud相关的属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。因为config的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties。

③启动类

 

@SpringBootApplication
public class ConfigClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigClientApplication.class, args);
	}
}

④Web测试

使用@Value注解来获取server端参数的值

 

@RestController
class HelloController {
    @Value("${neo.hello}")
    private String hello;

    @RequestMapping("/hello")
    public String from() {
        return this.hello;
    }
}

启动项目后访问:http://localhost:8002/hello,返回:hello im dev update说明已经正确的从server端获取到了参数。到此一个完整的服务端提供配置服务,客户端获取配置参数的例子就完成了。
 

我们在进行一些小实验,手动修改neo-config-dev.properties中配置信息为:neo.hello=hello im dev update1提交到github,再次在浏览器访问http://localhost:8002/hello,返回:neo.hello: hello im dev update,说明获取的信息还是旧的参数,这是为什么呢?因为springboot项目只有在启动的时候才会获取配置文件的值,修改github信息后,client端并没有在次去获取,所以导致这个问题。如何去解决这个问题呢?

三、Refresh

为了解决上面的问题,我们修改Client端,我们一修改配置,就给客户端发个POST请求,我们不但要解决上面问题,还要让客户端主动感知提交的代码从而主动的更新:

1.添加依赖


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

spring-boot-starter-actuator是一套监控的功能,可以监控程序在运行时状态,其中就包括/refresh的功能。

2.开启更新机制

需要给加载变量的类上面加载@RefreshScope,在客户端执行/refresh的时候就会更新此类下面的变量值。

@RestController
@RefreshScope // 使用该注解的类,会在接到SpringCloud配置中心配置刷新的时候,自动将新的配置更新到该类对应的字段中。
class HelloController {

    @Value("${neo.hello}")
    private String hello;

    @RequestMapping("/hello")
    public String from() {
        return this.hello;
    }
}

在这种模式下,我们先请求服务端

http://localhost:8001/neo-config-dev.properties

返回:

neo.hello: hello im dev update

然后我们请求客户端

http://localhost:8002/hello

返回:

hello im dev update bus

我们手动修改配置文件,请求服务端:

neo.hello: hello im dev update bus edit

这时候我们手动执行:

curl -X POST http://localhost:8002/bus/refresh

请求客户端:

neo.hello: hello im dev update bus edit


四、配置中心服务化

1.服务端改造

⑴添加依赖


	
		org.springframework.cloud
		spring-cloud-config-server
	
	
		org.springframework.cloud
		spring-cloud-starter-eureka
	

⑵配置文件

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8000/eureka/   ## 注册中心eurka地址

⑶启动类

启动类添加@EnableDiscoveryClient激活对配置中心的支持

@EnableDiscoveryClient
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigServerApplication.class, args);
	}
}

然后我们启动一个Eureka服务,再启动上面的启动类,可以看到已经注册上去了,这里我们可以将服务端改为高可用模式

2.客户端改造

⑴添加依赖


	
		org.springframework.cloud
		spring-cloud-starter-config
	
	
		org.springframework.boot
		spring-boot-starter-web
	
	
		org.springframework.cloud
		spring-cloud-starter-eureka
	
	
		org.springframework.boot
		spring-boot-starter-test
		test
	

⑵配置文件

spring.application.name=spring-cloud-config-client
server.port=8002

spring.cloud.config.name=neo-config
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=spring-cloud-config-server

eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

主要是去掉了spring.cloud.config.uri直接指向server端地址的配置,增加了最后的三个配置:

spring.cloud.config.discovery.enabled :开启Config服务发现支持
spring.cloud.config.discovery.serviceId :指定server端的name,也就是server端spring.application.name的值
eureka.client.serviceUrl.defaultZone :指向配置中心的地址
这三个配置文件都需要放到bootstrap.properties的配置中

⑶启动类

启动类添加@EnableDiscoveryClient激活对配置中心的支持

@EnableDiscoveryClient
@SpringBootApplication
public class ConfigClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigClientApplication.class, args);
	}
}

启动client端,在浏览器中访问:http://localhost:8000/ 就会看到server端和client端都已经注册了到注册中心了。
 

五、基于Webhook和消息总线的解决方案

1.基本原理图

这时Spring Cloud Bus做配置更新步骤如下:

⑴提交代码触发post请求给bus/refresh

server端接收到请求并发送给Spring Cloud Bus

⑶Spring Cloud bus接到消息并通知给其它客户端

⑷其它客户端接收到通知,请求Server端获取最新配置

⑸全部客户端均获取到最新的配置

2.客户端

⑴添加依赖

需要多引入spring-cloud-starter-bus-amqp包,增加对消息总线的支持


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

⑵修改配置文件

## 刷新时,关闭安全验证
management.security.enabled=false
## 开启消息跟踪
spring.cloud.bus.trace.enabled=true

spring.rabbitmq.host=192.168.9.89
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123456

3.服务端

⑴添加依赖

需要多引入spring-cloud-starter-bus-amqp包,增加对消息总线的支持


	
		org.springframework.cloud
		spring-cloud-config-server
	
	
		org.springframework.cloud
		spring-cloud-starter-bus-amqp
	
	
		org.springframework.cloud
		spring-cloud-starter-eureka
	

⑵修改配置文件

server:
  port: 8001
spring:
  application:
    name: spring-cloud-config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/ityouknow/spring-cloud-starter/     # 配置git仓库的地址
          search-paths: config-repo                             # git仓库地址下的相对地址,可以配置多个,用,分割。
          username: username                                        # git仓库的账号
          password: password                                    # git仓库的密码
  rabbitmq:
    host: 192.168.0.6
    port: 5672
    username: admin
    password: 123456

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8000/eureka/   ## 注册中心eurka地址


management:
  security:
     enabled: false   //配置文件要注意格式,要不无效!!!

4.测试

我们将github上的文件

neo.hello=hello im dev update bus edit edit 

改成:

neo.hello=hello im dev update bus edit edit zuizhong

然后执行一个CURL:

curl -X POST http://localhost:8001/bus/refresh

然后读8001(配置服务器端):

http://localhost:8001/neo-config-dev.properties

显示:

neo.hello: hello im dev update bus edit edit zuizhong

然后我们读:

8002客户端:

http://localhost:8002/hello

输出:

hello im dev update bus edit edit zuizhong

8003客户端:

http://localhost:8003/hello

输出:

hello im dev update bus edit edit zuizhong

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(分布式,SpringCloud)