配置中心

内容纲要

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

常规的配置定义

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

    配置管理缺点

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

    配置项的静态内容

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

      配置项的动态内容

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

      配置管理的需求

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

    准备

    创建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>

    添加参数和启动类

  • 启动类
    /**
    * @description: some desc
    * @author: Binlin B Wang
    * @email: binlin.b.wang@cn.pwc.com
    * @date: 2022/5/19 14:29
    */
    @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. 第一种
  • http://localhost:60000/{application}/{profile}/{label}
  • http://localhost:60000/config-consumer/prod
  • 可以再最后加上label,默认为master
  • http://localhost:60000/config-consumer/prod/master
    1. 第二种
  • http://localhost:60000/{label}/{application}-{profile}.yml (.json,.properties)
  • http://localhost:60000/config-consumer-prod.yml
  • http://localhost:60000/config-consumer-prod.properties
  • http://localhost:60000/config-consumer-prod.json
  • 如果需要添加label则直接再端口后接label
  • http://localhost:60000/master/config-consumer-prod.yml

    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;
}

}

# 动态拉去参数
## 引入特殊依赖
```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.3.5.RELEASE</version>
</dependency></code></pre>
<h2>改造config-client</h2>
<ol>
<li>
<p>新增controller</p>
<pre><code class="language-java">@RestController
@RequestMapping("/refresh")
// 动态刷新配置信息
@RefreshScope
public class RefreshController {

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

@GetMapping("/word")
public String getWord(){
    return word;
}
}</code></pre>
</li>
<li>新增配置内容bootstrap.yml
<pre><code class="language-json">management:
security:
enabled: false
endpoints:
web:
  exposure:
    include: "*"
endpoint:
health:
  show-details: always</code></pre></li>
<li>
<p>通过actuator暴露继续刷新修改后的内容
post 类型接口:<a href="http://localhost:61000/actuator/refresh">http://localhost:61000/actuator/refresh</a></p>
<h1>配置中心高可用</h1>
<ul>
<li>Config的高可用方式:Eureka注册中心进行集群处理</li>
<li>其他高可用方式:服务发起请求,网管进行负载均衡
<h2>Eureka高可用</h2>
<h3>config-server项注册中心报道</h3></li>
<li>创建 config-server-eureka项目</li>
<li>新增依赖
<pre><code class="language-xml"><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></code></pre></li>
<li>新增配置文件
```yml
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/

  • 创建主类
  • /**
    * @description: some desc
    * @author: Binlin B Wang
    * @email: binlin.b.wang@cn.pwc.com
    * @date: 2022/5/19 14:29
    */
    @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依赖
    
        org.springframework.cloud
        spring-cloud-starter-netflix-eureka-client
    
    • 在启动类上加`@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

    encrypt:
      # 加密的key
      key: clay
    • 使用get类型请求访问验证状态: http://localhost:60001/encrypt/status

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

    • 加密和解密在config-server
    • 加密: post请求发起text/plain数据类型到http://localhost:60001/encrypt
    • 解密: post请求发起text/plain数据类型到http://localhost:60001/decrypt

      GitHub修改

    # {cipher}通知config-server需要解密
    food: '{cipher}6dfc2702b50b1f77195ab4316617a0e87e6b54c1aae4d6f27e155205bce1aca4'
    THE END
    分享
    二维码
    < <上一篇
    下一篇>>