Spring Cloud系列之Spring Cloud Config

认识Spring Cloud Config

Spring Cloud Config是最早的配置中心,虽然后面的之秀Nacos可以取代它, 但是Spring Cloud Config还是很多公司在用,比如我司。

那为什么我们需要一个配置中心呢?我们直接将配置写在本地的yml配置文件中不行吗?

一个新技术的出现,一定是因为它解决了某些痛点,我们来看看将配置信息直接写在本地yml配置文件存在哪些痛点:

  • 如果多个微服务可能使用相同的配置信息,假设有50个微服务,如果配置需要修改配置文件,就意味着我们需要修改50个微服务的yml文件,极其浪费时间。
  • 配置信息修改后,必须重启服务才能生效

而Spring Cloud Config解决了这俩个痛点:

  • 集中式管理。在开发中多个微服务可能使用相同的配置,假设有50个微服务,如果配置需要修改配置文件,就意味着我们需要修改50个微服务的yml文件。使用配置中心后,就可以做到一处修改,处处修改。
  • 动态修改配置。使用配置中心,配合actuator可以实现配置的动态修改,无需重启服务

Spring Cloud Config架构图

Spring Cloud系列之Spring Cloud Config_第1张图片
简单说明一下流程

  1. 把配置文件放在Git Repository中。
  2. Config Server从Git repository中读取配置信息。
  3. 其他客户端再从Config Server中加载配置文件

接下来,我们将根据这个架构图搭建一个案例。

快速入门Spring Cloud Config

项目中使用到的版本:

  • Spring Boot:2.2.2.RELEASE
  • Spring Cloud:Hoxton.SR1

版本不同的话可能会出现一点问题。

创建配置中心仓库

首先我们需要一个创建一个配置中心仓库。由于github的网速太慢,所以我使用码云创建配置中心仓库,当然你也可以使用github。

1、在码云创建springcloud-config仓库

2、在仓库中创建三个文件
Spring Cloud系列之Spring Cloud Config_第2张图片

文件命名规格:{项目名}-{配置环境版本}.yml。比如config-dev.yml,表示的是config项目的开发环境配置。

配置文件内容分别如下。

config-dev.yml:

user:
  name: "张三 dev" 

config-prod.yml

user:
  name: "张三 prod" 

config服务端搭建

1、 新建SpringBoot项目spring-cloud-config-server,并引入依赖

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>Hoxton.SR1version>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>

<dependencies>
    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-config-serverartifactId>
    dependency>
dependencies>

3.2 配置config相关配置

bootstrap.yml 文件

spring:
  application:
    name: config-server  # 应用名称
  cloud:
    config:
      server:
        git:
          # 配置中心仓库地址
          uri: https://gitee.com/F_promise/springcloud-config.git #配置文件所在仓库
          username: 码云用户名
          password: 码云密码
          default-label: master #配置文件分支
#          search-paths: config  #配置文件所在根目录

3、在 Application 启动类上增加相关注解 @EnableConfigServer

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

启动SpringBoot服务,测试一下。

Spring Cloud Config 有它的一套访问规则,我们通过这套规则在浏览器上直接访问就可以。

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
  • application:应用名,这里是config
  • profile:配置文件版本,比如dev、prod
  • label:git的分支,默认master

以第一条规则为例,访问config-dev.yml配置文件:
Spring Cloud系列之Spring Cloud Config_第3张图片
至此,配置中心服务端搭建完毕,接下来客户端(其他项目)需要从配置中心中获取配置信息。

config客户端搭建

1、新建SpringBoot项目spring-cloud-config-client,并引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>

    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-configartifactId>
    dependency>
dependencies>

注意,客户端和服务端引入的config依赖是不一样的。

2、编写bootstrap.yml配置文件

--- bootstrap.yml ---
spring:
  profiles:
    active: dev		#激活开发环境的配置文件
    
---
spring:
  application:
    name: config
  cloud:
    config:
      uri: http://localhost:8080	#config服务端的地址
      label: master					
      profile: dev					#开发环境

---
spring:
  application:
    name: config
  cloud:
    config:
      uri: http://localhost:8080 	#config服务端的地址
      label: master
      profile: prod					#生产环境

3、编写application.yml配置文件

server:
  port: 8888

user:
  name: 小王			#配置默认值。配置中心有用配置中心的

4、创建UserController测试使用

@RestController
public class UserController {

    @Value("${user.name}")
    private String name;

    @GetMapping("info")
    public String info(){
        return name;
    }
}

5、启动服务,访问测试
Spring Cloud系列之Spring Cloud Config_第4张图片
可以看到,成功读取到了配置中心中的config-dev.yml配置文件。将bootstrap.yml中的active改成prod在进行测试:
Spring Cloud系列之Spring Cloud Config_第5张图片

实现自动刷新

Spring Cloud Config是在项目启动的时候加载的配置内容,导致了它存在一个缺陷,配置文件修改后,需要重启服务才能生效。这也是我们之前说的第二个痛点。

为了解决这个痛点,它提供了一个刷新机制,但是需要我们主动出发。那就是 @RefreshScope 注解并结合 actuator 。

actuator实现自动刷新

1、在spring-cloud-config-client加入actuator依赖

<dependency>
	<groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-actuatorartifactId>
dependency>

2、在application.yml中添加如下actuator的配置

management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

3、在Controller上添加@RefreshScope注解

@RestController
@RefreshScope
public class UserController {

    @Value("${user.name}")
    private String name;

    @GetMapping("info")
    public String info(){
        return name;
    }
} 	

4、主动触发更新

在配置文件修改后,使用Postman发送一个post请求到http://localhost:8888/actuator/refresh 这个接口,触发主动更新。
Spring Cloud系列之Spring Cloud Config_第6张图片

Spring Cloud Bus

Spring Cloud Bus 将分布式系统的节点与轻量级消息代理链接。这可以用于广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,Bus 就像一个扩展的 Spring Boot 应用程序的分布式执行器,但也可以用作应用程序之间的通信渠道。
—— Spring Cloud Bus 官方解释

如果每次配置文件修改后,都需要我们主动发送post请求触发更新,这明显有点不太方便。而且如何客户端比较多的话,一个一个的手动刷新也比较耗时。这个时候,我们可以借助Spring Cloud Bus的广播功能,让client端都订阅配置更新事件,当配置更新时,触发其中一个端的更新事件,Spring Cloud Bus就把此事件广播到其他订阅端,以此来达到批量更新。

1、Spring Cloud Bus 核心原理其实就是利用消息队列做广播,所以要先有个消息队列,目前官方支持 RabbitMQ 和 kafka。我们这里以RabbitMQ 为例。

2、在客户端spring-cloud-config-client中加入依赖

<dependency>
     <groupId>org.springframework.cloudgroupId>
     <artifactId>spring-cloud-starter-bus-amqpartifactId>
 dependency>

3、在配置文件中增加 RabbitMQ 相关配置

spring: 
  rabbitmq:
    host: 192.168.243.136
    port: 5672
    username: guest
    password: guest

4、启动俩个或多个客户端进行测试

我们可以拷贝一份配置
Spring Cloud系列之Spring Cloud Config_第7张图片
然后修改vm options添加-Dserver.port=8889就行了
Spring Cloud系列之Spring Cloud Config_第8张图片
所以最后的结构就是俩个客户端和一个配置中心服务端。
Spring Cloud系列之Spring Cloud Config_第9张图片

5、分别打开 http://localhost:8888/info和 http://localhost:8889/info,查看内容,然后修改码云上配置文件的内容并提交。再次访问这两个地址,数据没有变化。

6、访问其中一个的 actuator/bus-refresh 地址,注意还是要用 POST 方式访问。之后查看控制台输出,会看到这两个端都有一条这样的日志输出

o.s.cloud.bus.event.RefreshListener: Received remote refresh request. Keys refreshed

7、再次访问第 5 步的两个地址,会看到内容都已经更新为修改后的数据了。

结合 Eureka 使用 Spring Cloud Config

以上是Spring Cloud Config最基本的使用,在实际开发中,Spring Cloud Config可能会被注册在Eureka中,这样的话,可以Spring Cloud Config配置中心就可以搭建集群实现高可用。

此外引入Eureka后,config客户端就不再需要直接和config服务端直接打交道了,而是通过Eureka来发现Config服务端。

加入Eureka后的架构图如下:
Spring Cloud系列之Spring Cloud Config_第10张图片
简单说明一下流程

  1. 把配置文件放在Git Repository中。
  2. Config Server从Git repository中读取配置信息。
  3. Config Server将自己注册到Eureka中
  4. Client从Eureka中获取Config Server的信息
  5. Client访问Config Server,加载配置信息

搭建Eureka服务

首先搭建一个简单的Eureka。如果你没有学过Eureka的话,可以看看这篇文章Spring Cloud系列之Eureka入门使用。

1、导入依赖

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>

2、编写配置文件

spring:
  application:
    name: eureka-server

server:
  port: 3000

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url.defaultZone: http://localhost:3000/eureka/

3、在启动类标记@EnableEurekaServer注解

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

将配置中心注册到Eureka中

1、给spring-cloud-config-server项目添加Eureka依赖

<dependency>
     <groupId>org.springframework.cloudgroupId>
     <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
 dependency>

2、在配置文件中添加Eureka相关配置

eureka:
  client:
    service-url:
      #注册到eureka服务端的地址
      defaultZone: http://localhost:3000/eureka/
  instance:
    #点击具体的微服务,右下角是否显示ip
    prefer-ip-address: true
    #显示微服务的名称
    instance-id: spring-cloud-config-server

3、给主启动类添加@EnableEurekaClient注解

启动配置中心后,访问Eureka
Spring Cloud系列之Spring Cloud Config_第11张图片

config客户端从Eureka中发现配置中心

1、给spring-cloud-config-client项目添加Eureka依赖

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>

2、修改配置文件,添加Eureka的相关配置,并指定配置中心的application.name

spring:
  profiles:
    active: dev		#激活开发环境的配置文件

eureka:
  client:
    service-url:
      #注册到eureka服务端的地址
      defaultZone: http://localhost:3000/eureka/
  instance:
    #点击具体的微服务,右下角是否显示ip
    prefer-ip-address: true
    #显示微服务的名称
    instance-id: spring-cloud-config-client

---
spring:
  application:
    name: config
  cloud:
    config:
#      uri: http://localhost:8080	#config服务端的地址,整合eureka后不需要填写
      label: master
      profile: dev					#开发环境
      discovery:                    #从Eureka中发现配置中心
        enabled: true
        service-id: config-server   #指定配置中心的application.name

---
spring:
  application:
    name: config
  cloud:
    config:
#      uri: http://localhost:8080 	#config服务端的地址
      label: master
      profile: prod					#生产环境
      discovery:                    #从Eureka中发现配置中心
        enabled: true
        service-id: config-server   #指定配置中心服务端的server-id

整合Eureka后,config客户端不再需要指定config服务端的地址,而是通过config服务端的application.name从Eureka中获取配置中心的信息。配置中心可以做集群高可用。

3、给主启动类添加@EnableEurekaClient注解

启动后,查看Eureka,访问http://localhost:8888/info进行测试。
Spring Cloud系列之Spring Cloud Config_第12张图片
在这里插入图片描述

参考文章:
https://cloud.tencent.com/developer/article/1474037

你可能感兴趣的:(springcloud)