SpringCloud Config 分布式配置中心

分布式系统面临的配置问题:微服务意味着将单体应用拆分成一个个自服务,这些服务都是要相应的配置信息才能运行,随着系统内微服务数量越来越多,配置信息也不断地增多,所以一套集中式的、动态的配置管理设施是必不可少的。

概述

  • SpringCloud Config是一个提供外部集中式配置管理的设施,配置服务器为各种不同的额微服务应用提供了一个中心化的外部配置
  • SpringCloud Config分为客户端和服务端两部分
  1. 服务端:分布式配置中心,是一个独立的微服务,用来连接并为客户端提供配置信息,加密/解密信息等访问接口
  2. 客户端:通过指定的配置中心获取配置资源,cloud推荐用git来存储配置信息
  • SpringCloud Config解决的问题:
  1. 集中管理配置文件
  2. 不同环境不同配置,动态化的配置更新
  3. 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,让服务中心统一为服务拉取配置文件
  4. 当配置发生变动时,服务不需要重启即可感知配置变化并应用
  5. 将配置信息以REST接口形式暴露

![SpringCloud Config架构图](images\SpringCloud Config架构图.png)

SpringCloud Config服务端与Github通讯

目标:将配置文件部署在github,Config服务端从github获取配置

案例

  1. 新建ConfigServer模块并配置pom.xml
<!-- springCloud Config -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</artifactId>
		</dependency>
		<!-- 避免Config的Git插件报错:org/eclipse/jgit/api/TransportConfigCallback -->
		<dependency>
			<groupId>org.eclipse.jgit</groupId>
			<artifactId>org.eclipse.jgit</artifactId>
			<version>4.10.0.201712302008-r</version>
		</dependency>


  1. 建立远程仓库,并上传配置文件。如下例
spring: 
    profiles: 
        active:
           - dev
---
spring:
    profiles: dev
    application:
        name: microservicecloud-config-XXX-dev
---
spring:
    profiles: test
    application:
        name: microservicecloud-config-XXX-test


  1. 在application.xml文件中配置github地址
server:
  port: 3344

spring:
  application:
    #为这个服务取名,非常重要!!!!!
    name: microservicecloud-config
  cloud:
    config:
      server:
        git:
          # uri填github上仓库地址
          uri: https://github.com/XXXX/SpringCloud_Configuration.git


  1. 编写主启动类,加入@EnableConfigServer注解
@SpringBootApplication
@EnableConfigServer
public class ConfigServer3344_APP {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServer3344_APP.class,args);
    }
}


  1. 启动服务并尝试访问配置文件,有以下五种访问配置规则
  • {application}:配置文件的文件名
  • {profile}:读取的环境
  • {lable}:分支
/{application}/{profile}[/{lable}]
/{application}-{profile}.yml
/{lable}/{application}-{profile}.yml
/{application}-{profile}.properties
/{lable}/{application}-{profile}.properties


可用例子(返回格式可能不大相同,但返回值相同):

  • http://config3344.com:3344/application-test.yml
  • http://config3344.com:3344/master/application-dev.yml
  • http://config3344.com:3344/application-test.yml/master

不可用例子:

  • 没有该环境,返回空值:http://config3344.com:3344/application-test11.yml/master
  • 没有配置文件,犯回错误页面:http://config3344.com:3344/lkjliiusdfsddsfl.yml

bootstrap.yml介绍

  • bootstrap.yml比application.yml具有更高的优先级。
  • bootstrap.yml是系统级的资源配置项,application.yml是用户级的资源配置项。
  • SpringCloud会创建"BootStrap Context"作为"ApplicationContext"的==父上下文==。初始化的时候BootStrap Context负责从外部源加载配置属性并解析。这两个上下文共享一个"Environment",BootStrap 具有更高优先级,他们不会被本地配置覆盖。

客户端的配置与测试

介绍:客户端主要是在==加载时==通过config server服务端获得github配置仓库的地址,进而通过目标配置文件的文件名获取相应的配置,最后将取得的配置对自身资源进行赋值并提供访问

实现过程

1.创建远程配置yml文件并上传到github上。如下测试案例因为需要进行测试,所以配置了两个profiles方便切换并观察

spring: 
    profiles: 
        active:
           - dev
---
server: 
    port: 8201
spring:
    profiles: dev
    application:
        name: microservicecloud-config-client-dev
eureka:
    client: 
        service-url: 
            defaultZone: http://eureka-dev.com:7001/eureka/
---
server: 
    port: 8202
spring:
    profiles: test
    application:
        name: microservicecloud-config-client-test
eureka:
    client: 
        service-url: 
            defaultZone: http://eureka-dev.com:7001/eureka/

  1. 本地创建config client模块,并配置好pom.xml,以下本组件是必选依赖
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>


  1. 编写bootstrap.yml配置文件,这个步骤比较关键,主要是根据此处的配置信息去寻找config server以获得github仓库地址和配置中的目标配置文件文件名

spring: cloud: config: name: application_config #需要从github上读取的资源名称,注意没有yml后缀名 profile: test #本次访问的配置项 label: master uri: http://config3344.com:3344 #本微服务启动后先去找3344号服务,通过SpringCloudConfig获取GitHub的服务地址


  1. application.yml文件在本module中其实是可写可不写的,为了习惯需要,还是给他写了个名字
spring:
  application:
    name: microservicecloud_config


  1. 修改host文件增加映射,和3344一样
  2. 编写主启动类,没什么特别的,最基本的主启动类
  3. 编写controller,此步骤也比较关键,主要是利用@Value注解赋值,若写错了bootstrap.yml中的配置文件名称而没有获取到配置,启动时这里会抛出异常。@Value中注解的参数即是目标配置文件中的参数值,使用El表达式获取
@org.springframework.web.bind.annotation.RestController
public class RestController {
    @Value("${server.port}")
    private String port;
    @Value("${eureka.client.service-url.defaultZone}")
    private String eurekaZone;
    @Value("${spring.application.name}")
    private String name;


    @GetMapping("/config")
    @Override
    public String toString() {
        return "RestController{" +
                "port='" + port + '\'' +
                ", eurekaZone='" + eurekaZone + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}


  1. 先启动config server服务,然后再启用本client服务,根据profiles的值访问对应的端口即可。如本例选择的是test,则访问端口为:http://config3355.com:8202/config。(config3355.com为hosts文件中配置了的映射)

SpringCloud的配置实战

介绍:其实前面client的配置案例都是帮助理解这个组件为主,并没有很大的实际意义。。。。。。这节的案例中是配置一个Provider,一个eureka,他们的配置统一在github上获取,实现统一配置分布式管理和多环境变更,这个才比较有实战意义。

实现过程

  1. 先写好provider和Eureka的配置yml文件,这两个文件和平常配置没什么不同,因为这里主要是说config,所以就没有配置集群,上传yml到github

Eureka配置文件示例:


spring: 
    profiles: 
        active:
           - dev
---
spring:
    profiles: dev
    application:
        name: microservicecloud-eureka-client-dev
server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001.com    #hostname为hosts文件中映射的地址
  client:
    register-with-eureka: false     #false表示不向注册中心注册自己
    fetch-registry: false           #false表示自己就是注册中心,职责是维护实例,不参加检索
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/   #设置eureka server的交互地址

---
spring:
    profiles: test
    application:
        name: microservicecloud-eureka-client-dev
server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001.com    #hostname为hosts文件中映射的地址
  client:
    register-with-eureka: false     #false表示不向注册中心注册自己
    fetch-registry: false           #false表示自己就是注册中心,职责是维护实例,不参加检索
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/    #设置eureka server的交互地址


Provider配置文件示例:


spring: 
    profiles: 
        active:
           - dev
---
server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml
  type-aliases-package: com.XXX.entity
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml
spring:
  profiles: dev
  application:
    name: microservicecloud-dept   #为这个服务取名,非常重要!!!!!
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://192.168.88.246:3306/cloudDB01
    username: root
    password: 123456
    dbcp2:
      min-idle: 5         #最小连接数
      initial-size: 5    #初始化连接数
      max-total: 10      #最大连接数
      max-wait-millis: 200  #等待连接最长的超时时间
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/
  instance:
    instance-id: dept8001
    prefer-ip-address: true
---
server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml
  type-aliases-package: com.XXX.entity
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml
spring:
  profiles: test
  application:
    name: microservicecloud-dept   #为这个服务取名,非常重要!!!!!
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://192.168.88.246:3306/cloudDB02
    username: root
    password: 123456
    dbcp2:
      min-idle: 5         #最小连接数
      initial-size: 5    #初始化连接数
      max-total: 10      #最大连接数
      max-wait-millis: 200  #等待连接最长的超时时间
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/
  instance:
    instance-id: dept8001
    prefer-ip-address: true


  1. 新开eureka和provide的模块并在pom.xml中添加依赖,其他必要依赖和之前的案例一样,但是config的依赖一定要添加上
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>


  1. 两个模块都要编写bootstrap.yml文件,和上面的案例一样

spring: cloud: config: name: application_config #需要从github上读取的资源名称,注意没有yml后缀名 profile: test #本次访问的配置项 label: master uri: http://config3344.com:3344 #本微服务启动后先去找3344号服务,通过SpringCloudConfig获取GitHub的服务地址


  1. (可选)两个模块中编写application.yml文件,可以配置一下服务名
spring:
  application:
    name: microservicecloud_config


  1. 两个模块的主启动类,Eureka的正常加EurekaServer注解,Provider加EurekaClient注解,不详述
  2. 编写Provider模块的业务代码
  3. 启动测试,因为这两个模块都要通过3344ConfigServer为其在github上获取配置,所以要先启动3344模块,然后再一次启动eureka和provider模块,进行测试即可。