SpringBoot + Spring Cloud +Vue 管理系统后台搭建(十七、配置中心Config、Bus)

本文详细介绍了SpringCloudConfig的使用,包括服务端和客户端的搭建,以及配置中心如何与Git仓库结合实现配置的版本管理。还探讨了SpringCloudBus如何实现实时刷新配置,以及使用RabbitMQ作为消息总线的配置。最后,文章通过实例演示了配置的更新和客户端的自动刷新过程。
摘要由CSDN通过智能技术生成

Spring Cloud Config官网:https://cloud.spring.io/spring-cloud-config/reference/html/

Spring Cloud Config是一套为分布式系统中的基础设施和微服务应用提供集中化配置的管理方案。分为服务端和客户端两个部分。服务端也称为分布式配置中心,是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息。客户端是微服务架构中的各个微服务应用或基础设施。它们通过指定的配置中心来管理服务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。

Spring Cloud Config对服务端和客户端中的环境变量和属性配置实现了抽象映射,所以除了适用于spring应用,也是可以在任何其他语言应用中实现的。Spring Cloud Config实现的配置中心默认采用Git来存储配置信息,所以使用Spring Cloud Config构建的配置服务器天然就支持对微服务应用配置信息的版本管理,并且可以通过Git客户端工具非常方便地管理和访问配置内容。当然它也提供了对其他存储方式的支持,比如SVN、本地化文件系统等。

 

第一步,Git配置

在git下创建存放文件目录config-repo,

文件内容为hello=hello, xxx  configurations.

 

第二步、服务端实现

新建mango-config工程,作为配置中心的服务端。负责把Git仓库的配置文件发布为RESTFul接口

配置pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.0.4.RELEASE</version>
      <relativePath /> <!-- lookup parent from repository -->
   </parent>

   <groupId>com.louis</groupId>
   <artifactId>mango-config</artifactId>
   <version>${project.version}</version>
   <packaging>jar</packaging>

   <name>mango-config</name>
   <description>mango-config</description>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <project.version>1.0.0</project.version>
      <java.version>1.8</java.version>
      <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
   </properties>

   <dependencies>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-config-server</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-consul-discovery</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-bus-amqp</artifactId>
      </dependency>
   </dependencies>

   <dependencyManagement>
      <dependencies>
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
      </dependencies>
   </dependencyManagement>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

修改启动类:

@EnableConfigServer //开启配置服务支持
@EnableDiscoveryClient // 开启服务发现支持
@SpringBootApplication
public class MangoConfigApplication {

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

}

修改配置文件

将application.properties改为application.yml

server:
  port: 8020
spring:
  application:
    name: mango-config
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        serviceName: ${spring.application.name}    # 注册到consul的服务名称
    config:
      label: master  # git仓库分支
      server:
        git:
          uri: https://gitee.com/****.git  # 配置git仓库的地址
          search-paths: src/config-repo  # git仓库地址下的相对地址,可以配置多个,用,分割。
          username: username  # git仓库的账号
          password: password  # git仓库的密码

http://localhost:8020/consumer/dev

访问:http://localhost:8020/consumer-dev.properties

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

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

  • /{application}/{profile}[/{label}]
  • /{application}-{profile}.yml
  • /{label}/{application}-{profile}.yml
  • /{application}-{profile}.properties
  • /{label}/{application}-{profile}.properties

以consumer-dev.properties为例子,它的application是consumer,profile是dev。client会根据填写的参数来选择读取对应的配置。

说明:开始我直接在git上创建了目录,创建文件,但是启动项目后访问没有返回配置的内容,找了好久没有找到问题原因,然后我把创建的文件删除了,直接上传本地写好的文件,访问就没有问题。

配置客户端

打开mango-consumer工程

添加pom依赖

<!-- spring-cloud-config -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

添加一个bootstrap.yml配置文件,添加配置中心,并把注册中心的配置移到这里,因为在通过配置中心查找配置时需要通过注册中心的发现服务。

bootstrap.yml

spring:
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        serviceName: ${spring.application.name}    # 注册到consul的服务名称
    config:
      discovery:
        enabled: true  # 开启服务发现
        serviceId: mango-config # 配置中心服务名称
      name: consumer  # 对应{application}部分
      profile: dev  # 对应{profile}部分
      label: master  # 对应git的分支,如果配置中心使用的是本地存储,则该参数无用

配置说明:

  • spring.cloud.config.uri:配置中心的具体地址
  • spring.cloud.config.name:对应{application}部分
  • spring.cloud.config.profile:对应{profile}部分
  • spring.cloud.config.label:对应git的分支。如果配置中心使用的是本地存储,则该参数无用
  • spring.cloud.config.discovery.service-id:指定配置中心的service-id,便于扩展为高可用配置集群。

上面这些与spring cloud相关的属性必须配置在bootstrap.yml中,这样config部分内容才能被正确加载。

因为config的相关配置会先于application.yml,而bootstrap.yml的加载也是先于application.yml文件的。

application.yml

server:
  port: 8005
spring:
  application:
    name: mango-consumer
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        serviceName: ${spring.application.name}    # 注册到consul的服务名称
  boot:
    admin:
      client:
        url: "http://localhost:8000"
  zipkin:
    base-url: http://localhost:9411/
  sleuth:
    sampler:
      probability: 1 #样本采集量,默认为0.1,为了测试这里修改为1,正式环境一般使用默认值。
# 开放健康检查接口
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS
#开启熔断器
feign:
  hystrix:
    enabled: true
    dashboard:
      proxy-stream-allow-list: "*"

控制器

添加一个 SpringConfigController 控制器, 添加注解 @Value("${comsumer.hello}"),声明hello属性从配置文件读取。

代码如下:

SpringConfigController.java
@RefreshScope
@RestController
class SpringConfigController {
    
    @Value("${hello}")
    private String hello;

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

访问:http://localhost:8005/hello

然后我们手动修改maven仓库下配置信息,在末尾加数字2,再访问http://localhost:8005/hello,发现并没有生效,

这是因为spring boot项目只有在启动的时候才会获取配置文件的内容,虽然git配置信息被修改了,但是客户端并没有重新获取,所以导致读的信息任然是旧的配置。

因此,我们需要一种通知刷新的机制来支持。所以有了Refresh机制。

Refresh机制

     Refresh机制是spring cloud config 提供的一种刷新机制,它允许客户端通过post方法触发各自的/refresh,只要依赖spring-boot-starter-actuator包,就有了refresh的功能,下面我们为客户端加上刷新功能。

1.添加pom依赖

<!--actuator-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

我们这里之前就添加过了,所以这里不做添加

2.添加注解

在使用的配置属性的类型上加@RefreshScope,这样客户端在执行refresh的时候就会刷新此类下面的配置属性。

@RefreshScope
@RestController
class SpringConfigController {
    
    @Value("${hello}")
    private String hello;

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

3.修改yml配置文件

在配置文件中开发Refresh的相关接口。

# 开放健康检查接口
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

我们这里之前已经添加好啦,所以就不做添加了

配置完成后,我们就重启服务,访问http://localhost:8005/hello

然后我们修改git配置信息为3

再访问发现并没有变,因为我们还没有调refresh方法。

通过工具或自写代码发送post请求 http://localhost:8005/actuator/refresh,刷新配置。

这里通过在线测试网站发送,地址:https://getman.cn/Mo2FX 。

发送后,我们再访问发现改变了

因为这个Refresh机制每次都需要手动刷新客户端还是很麻烦,如果客户端数量一多就简直难以忍受了,所以我们有了Spring Cloud Bus。

Spring Cloud Bus

Spring Cloud Bus,被大家称为消息总线,它通过轻量级的消息代理来连接各个分布的节点,可以利用像消息队列的广播机制在分布式系统中进行消息传播,通过消息总线可以实现很多业务功能,其中对于配置中心客户端刷新,就是一个非常典型的使用场景。

Spring Cloud Bus 进行配置更新步骤如下:

  1、提交代码触发post请求给/actuator/bus-refresh

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

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

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

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

配置步骤

安装RabbitMQ

因为我们需要用到消息队列,我们这里选择RabbitMQ

我们之前安装过docker环境,所以我们用docker进行安装

用下面命令安装RabbitMQ镜像

docker pull rabbitmq:management

执行完成后用docker images查看下载的镜像

 

运行下列命令启动,创建容器

docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management

启动成功之后,可以执行以下命令查看启动容器。

docker ps

 

 

启动成功后我们访问

http://localhost:15672/http://宿主机IP:15672/

系统默认提供的用户名和密码是guest

输入账户密码登录

 

 客户端实现

我们需要在mango-consumer中添加消息总线相关依赖

1、添加依赖

<!-- bus-amqp -->
      <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

2、修改配置

在bootstrap.yml配置文件中添加RebbitMQ相关配置

  rabbitmq:
    host: localhost
    port: 5672
    username: username
    password: password

服务端实现

在mango-config中添加相关依赖

1、添加依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

2、修改配置

在yml文件中添加RebbitMQ和接口开放相关配置

  rabbitmq:
    host: localhost
    port: 5672
    username: username
    password: password
management:
  endpoints:
    web:
      exposure:
        include: "*"

到此,我们已完成相关配置,下面启动测试

启动客户端报错

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'configServerRetryInterceptor' available
解决方法是添加一个RetryConfiguration类和spring.factories配置文件

RetryConfiguration.java

public class RetryConfiguration {
    @Bean
    @ConditionalOnMissingBean(name = "configServerRetryInterceptor")
    public RetryOperationsInterceptor configServerRetryInterceptor() {
        return RetryInterceptorBuilder.stateless().backOffOptions(1000, 1.2, 5000).maxAttempts(10).build();
    }
}

spring.factories

org.springframework.cloud.bootstrap.BootstrapConfiguration=com.louis.mango.consumer.RetryConfiguration

然后重启服务访问http://localhost:8005/hello

然后我们修改git配置信息为10

再访问http://localhost:8005/hello,发现还是没有变

再用工具发送post请求 http://localhost:8020/actuator/bus-refresh 。

这次是向注册中心服务端发送请求,发送成功之后服务端会通过消息总线通知所有的客户端进行刷新。

另外开启消息总线后的请求地址是 /actuator/bus-refresh,不再是refresh了

再访问发现以改变,这里可能需要一点时间刷新

到此,我们就完成了后端部分,希望对大家有所帮助。

看完记得点赞哦!!!

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值