配置中心

235 阅读4分钟

配置中心再微服务中的应用

常规的配置定义

  1. 程序 Hardcode 写死再代码中
  2. 配置文件,万年不变的配置 application.yml| bootstrap.yml
  3. 环境变量 操作系统层面和设置启动参数
  4. 数据存储 压力大,数据库可能承受不了

配置管理缺点

  1. 格式不统一---json,properties,yml
  2. 没有版本控制---放飞自我想改就改
  3. 基于静态配置---修改,发布流程繁琐(直接写在代码中的配置)
  4. 分布零散---没用统一管理

配置项的静态内容

  1. 环境配置
    1. 数据库连接串
    2. Eureka注册中心
    3. Kafka连接
    4. 应用名称
  2. 安全配置(加密)
    1. 连接密码
    2. 公钥私钥
    3. HTTP连接Cert

配置项的动态内容

  1. 功能控制
    1. 功能开关
    2. 人工熔断
    3. 蓝绿发布
    4. 数据源切换
  2. 业务规则
    1. 当日外汇利率
    2. 动态文案
    3. 规则引擎参数
  3. 应用参数
    1. 网管黑白名单
    2. 缓存过期时间
    3. 日志MDC设置

配置管理的需求

  1. 高可用
  2. 版本管理
    1. 修改记录
    2. 版本控制,权限控制
  3. 业务需求
    1. 内容加密
    2. 动态推动变更
  4. 配置分离,中心化管理

准备

创建GitHub配置仓库

1 创建GitHub仓库

  • 创建config-repo名的公共仓库

2 文件命名规则(文件名不能随便起)

  • Application(应用名称) & Profile(项目环境) {application}-{profile}.yml

{application}-{profile}.properties

  • Labe - 代码分支的名称

3 添加配置文件和属性

# comfig-consumer-dev.yml
info:
 profile: dev
name: Saul
word: 'God bless me'
# comfig-consumer-prod.yml
info:
 profile: prod
name: Paul
word: 'God bless you'

搭建配置中心

创建config-server项目引入依赖

# pom.xml
<artifactId>config-server</artifactId>
<name>config-server</name>
<packaging>jar</packaging>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
</dependencies>

添加参数和启动类

  • 启动类
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(ConfigServerApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }
}
  • application.yml配置文件
server:
  port: 60000
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/afterglow-now/config-repo.git
          # 子目录,可以支持多个文件或者通配符
          search-paths: abc,def,def*
          # 解决could not be established because of SSL problems错误
          skipSslValidation: true
          # 用户名
          username:
          # 密码
          password:
          # 强制拉去资源文件
          force-pull: true

通过GET请求拉去文件(URL的几种Pattern)

  1. 第一种
  1. 第二种

Client直连配置中心

创建config-client项目引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <!--在SpringCloud 2020.* 版本把bootstrap禁用了,导致在读取文件的时候读取不到而报错-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
</dependencies>

配置启动项和启动类

@SpringBootApplication
public class ConfigClientApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(ConfigClientApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }
}

注入GitHub属性到测试用例

  • bootstrap.yml
server:
  port: 61000

spring:
  application:
    name: config-client
  cloud:
    config:
      uri: http://localhost:60000
      profile: dev
      label: main
      name: config-consumer
  • controller类
@RestController
public class Controller {

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

    @Value("${myWord}")
    private String word;

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

    @GetMapping("/word")
    public String getWord(){
        return word;
    }

}

动态拉去参数

引入特殊依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.3.5.RELEASE</version>
</dependency>

改造config-client

  1. 新增controller
@RestController
@RequestMapping("/refresh")
// 动态刷新配置信息
@RefreshScope
public class RefreshController {

    @Value("${word}")
    private String word;

    @GetMapping("/word")
    public String getWord(){
        return word;
    }
}
  1. 新增配置内容bootstrap.yml
management:
  security:
    enabled: false
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always
  1. 通过actuator暴露继续刷新修改后的内容 post 类型接口:http://localhost:61000/actuator/refresh

配置中心高可用

  • Config的高可用方式:Eureka注册中心进行集群处理
  • 其他高可用方式:服务发起请求,网管进行负载均衡

Eureka高可用

config-server项注册中心报道

  • 创建 config-server-eureka项目
  • 新增依赖
<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>
  • 新增配置文件
server:
 port: 60001
spring:
 application:
   name: config-server-eureka
 cloud:
   config:
     server:
       git:
         uri: https://github.com/afterglow-now/config-repo.git
         # 强制拉去资源文件
         force-pull: true
         # 解决could not be established because of SSL problems错误
         skipSslValidation: true
eureka:
 instance:
   preferIpAddress: true
   instance-id: ${spring.cloud.client.ip-address}:${server.port}
 client:
   service-url:
     defaultZone: http://localhost:20000/eureka/
  • 创建主类
@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigServerEurekaApplication {
   public static void main(String[] args) {
       new SpringApplicationBuilder(ConfigServerEurekaApplication.class)
               .web(WebApplicationType.SERVLET)
               .run(args);
   }
}

config-client从注册中心获取config-server地址

  • 在config-client中新增eureka依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
  • 在启动类上加@EnableDiscoveryClient注解
  • 修改application.yml文件
server:
  port: 61000

spring:
  application:
    name: config-client
  cloud:
    config:
#      uri: http://localhost:60000
      discovery:
        enabled: true
        service-id: config-server-eureka
      profile: dev
      label: main
      name: config-consumer

eureka:
  instance:
    preferIpAddress: true
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
  client:
    service-url:
      defaultZone: http://localhost:20000/eureka/
      
management:
  security:
    enabled: false
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always

配置属性使用密钥对称加密

在JDK中替换JCE

改造config-server并生成加密字符串

  • 添加bootstrap.yml文件
encrypt:
  # 加密的key
  key: clay

修改GitHub文件,启动服务拉去配置

GitHub修改

# {cipher}通知config-server需要解密
food: '{cipher}6dfc2702b50b1f77195ab4316617a0e87e6b54c1aae4d6f27e155205bce1aca4'