Config配置中心

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

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

Spring Cloud Config分为服务端和客户端两部分:

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

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

作用:

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

环境搭建

创建git资源库

  1. 在Gitlab上创建资源库,例如:springcloud-config,默认为master分支

  2. 将本地的ssh公钥上传至gitlab

  3. 从gitlab上将资源库克隆下来

    1. git clone git@192.168.29.139:gitlab/springcloud-config.git
  1. 编写测试用的配置文件 dbconfig-dev.yml
    1. spring:
    2. datasource:
    3. type: com.alibaba.druid.pool.DruidDataSource
    4. url: jdbc:oracle:thin:@localhost:1521/orcl
    5. driver-class-name: oracle.jdbc.driver.OracleDriver
    6. username: myData
    7. password: tiger
  1. 将该文件上传至资源库
    git add *
    git commit -m "add database config"
    git push
    

创建配置中心服务端

  1. 创建maven工程

  2. 加入pom依赖

    <dependencies>
     <!-- 配置中心服务端依赖 -->
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-config-server</artifactId>
     </dependency>
    
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-devtools</artifactId>
     </dependency>
     <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
     </dependency>
    </dependencies>
    
  1. 编写配置文件 ```yaml server: port: 3344 spring: application: name: cloud-config-center cloud: config: server:
     git:
       # git仓库地址,如果没有添加ssh公钥或者使用http协议,还需配置username、password属性
       uri: git@192.168.29.139:gitlab/springcloud-config.git
       # 搜索的目录
       search-paths:
         - springcloud-config
    

    读取的分支

    label: master

将配置中心注册到注册中心

eureka: client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://localhost:7001/eureka



4. 
编写主配置类
```java
@SpringBootApplication
@EnableConfigServer  // 配置中心服务端
public class ConfigCenterMain3344 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigCenterMain3344.class, args);
    }
}

验证:

可以通过以下形式访问配置信息:

  • /{application}/{profile}[/{label}]

    输出的是 JSON 格式,包含配置文件路径、版本号、分支、环境名、文件中配置内容等。

  • /{application}-{profile}.yml

    输出的是yaml文件内容。默认找master分支

  • /{label}/{application}-{profile}.yml

    输出的是yaml文件内容。

  • /{application}-{profile}.properties

  • /{label}/{application}-{profile}.properties

例如访问:http://cold-thunder:3344/master/dbconfig-dev.ymlhttp://cold-thunder:3344/dbconfig-dev.yml、[http://cold-thunder:3344/dbconfig/dev](http://cold-thunder:3344/dbconfig/dev) 看能否读取到配置信息

bootstrap.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配置的分离。

创建配置中心客户端

  1. 创建maven工程

  2. 加入pom依赖

    <dependencies>
     <!-- 加入配置中心客户端的starter依赖 -->
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-config</artifactId>
     </dependency>
    
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-devtools</artifactId>
     </dependency>
     <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
     </dependency>
    </dependencies>
    
  1. 编写bootstrap.yml配置文件 ```yaml server: port: 3355

spring: application: name: cloud-config-client3355 cloud: config:

  # 分支名称
  label: master
  # 配置文件名
  name: dbconfig
  # 配置文件的环境名后缀
  profile: dev

uri: http://localhost:3344 # 配置中心地址

  # 从注册中心中查找指定服务名的配置中心
  discovery:
    service-id: CLOUD-CONFIG-CENTER # 注册中心中的配置中心服务名
    enabled: true # 启动从注册中心获取服务

eureka: client: fetch-registry: true register-with-eureka: false service-url: defaultZone: http://localhost:7001/eureka



4. 
编写主启动类
```java
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain3355 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClientMain3355.class, args);
    }
}
  1. 编写测试用的Controller

    @RestController
    public class ConfigClientController {
     // 测试看能否读取到配置中心中配置的数据库用户名
     @Value("${spring.datasource.username}")
     private String username;
    
     @GetMapping("/getConfig")
     public String getConfig() {
         return username;
     }
    }
    

访问:http://localhost:3355/getConfig 测试看能否获取到配置中心中配置的用户名

动态刷新

配置中心的配置修改后,避免每次都需要重启客户端。

  1. 在配置中心客户端的pom中加入 actuator 监控的依赖
    <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
  1. 修改yaml,暴露监控端点
    # 暴露监控端点
    management:
    endpoints:
     web:
       exposure:
         include: "*"
    
  1. 在Controller上添加 @RefreshScope注解,使其拥有刷新的能力

    @RestController
    @RefreshScope  // 添加刷新注解
    public class ConfigClientController {
     @Value("${spring.datasource.username}")
     private String username;
    
     @GetMapping("/getConfig")
     public String getConfig() {
         return username;
     }
    }
    

此时,如果gitlab上的配置发生了改变,直接请求客户端的/getConfig获取到的还是以前的值。

如果想要gitlab上的配置生效,在gitlab上的配置发生改变后,还需手动向客户端的actuator发送一个 post 的刷新请求:

curl -X POST "http://localhost:3355/actuator/refresh"

然后再请求客户端的/getConfig时便可以获取到最新的值。

如果有多个微服务作为配置中心客户端,修改配置后每个都执行post请求很麻烦。因而可以使用消息总线。