服务配置中心(Config)

1、概述

①、问题出现

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

回顾我们以前创建的微服务,每一个module都有一个对应的application.yml文件,单拎出来服务提供者这几个module,如果每一个都用到了mybatis,且操作的都是同一个数据库,但是我们在每一个module都进行了一遍相同的数据库连接配置,这样的操作实在麻烦,如果我们没有一个统一的配置中心,当我们对数据库进行某些必要的修改后,我们就需要修改每一个module的配置,何其麻烦。再比如我们在开发的时候要使用一套开发环境,测试一套环境,上线又是一套环境,那微服务越来越多,修改起来难度是不是就越来越大啊。所以对于服务配置中心出现,是很有必要的。

image-20210215192004404

②、是什么配置中心

官方网站

SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。分为服务端和客户端两部分组成。

  • 服务端又称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口
  • 客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容

image-20210215194616431

③、能干什么

  • 集中管理配置文件
  • 不同环境不同配置,动态的配置更新,分环境部署如dev/test/prod/beta/release
  • 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
  • 当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置
  • 将配置信息以REST接口的形式暴露
  • Github整合:由于SpringcloudConfig默认使用Git来存储配置文件(也有其他方式,比如支持SVN和本地文件),但最推荐的是Git,而且使用http/https访问的形式

2、服务端配置与测试

①、新建一个Git仓库

image-20210216114525321

②、克隆到本地

这一步仅仅是为了方便自己本地修改仓库信息,与项目配置无关

image-20210216114642460

③、创建配置文件

image-20210216114847569

推送到远程

image-20210216115018038

④、新建module

image-20210216115207829

⑤、POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>SpringCloudDemo</artifactId>
        <groupId>com.phz.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>ConfigCenter3344</artifactId>

    <dependencies>
        <!--config server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>com.phz.springcloud</groupId>
            <artifactId>CloudAPI</artifactId>
            <version>1.0-SNAPSHOT</version>
        </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>
        <!--eureka client-->
        <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-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

⑥、YML

server:
  port: 3344

spring:
  application:
    name: config-center
  cloud:
    config:
      server:
        git:
          uri: https://github.com/PengHuAnZhi/CloudDemoConfig #Github上的git仓库地址
          ##搜索目录.这个目录指的是github上的目录
          search-paths:
            - CloudDemoConfig
      ##读取分支
      label: main

eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

⑦、主启动

/**
 * @author PengHuAnZhi
 * @createTime 2021/2/16 12:00
 * @projectName SpringCloudDemo
 * @className ConfigCenterMain3344.java
 * @description TODO
 */
@SpringBootApplication
@EnableConfigServer
public class ConfigCenterMain3344 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(ConfigCenterMain3344.class, args);
    }
}

⑧、配置hosts

添加config-3344.com映射127.0.0.1,路径为C:\Windows\System32\drivers\etc\hosts

image-20210216120707800

###########SpringCloudConfigCenter###########
127.0.0.1   config3344.com

⑨、测试

image-20210216121005720

通过ConfigCenter查看config-dev配置文件

http://config3344.com:3344/main/config-dev.yml

image-20210216121149473

修改config-dev配置文件,再次访问

image-20210216121442567

image-20210216121507549

3、客户端配置与测试

①、新建module

image-20210216144730419

②、POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>SpringCloudDemo</artifactId>
        <groupId>com.phz.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>ConfigClient3355</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.phz.springcloud</groupId>
            <artifactId>CloudAPI</artifactId>
            <version>1.0-SNAPSHOT</version>
        </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>
        <!--eureka client-->
        <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-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

③、YML

强调这个时候的yml配置文件需要命名为bootstrap,不再是applicationapplicaiton.yml是用户级的资源配置项bootstrap . yml是系统级的,优先级更加高。Bootstrap)属性有高优先级,默认情况下,它们不会被本地配置覆盖。Bootstrap contextApplication Context有着不同的约定,所以新增了一个bootstrap.yml文件,保证Bootstrap ContextApplication Context配置的分离。

Spring Cloud会创建一个“Bootstrap Context”,作为Spring应用的Application Context的父上下文。初始化的时候,BootstrapContext负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的``Environment’,换句话说就是分布式微服务种,我一个服务带着两份配置文件,一个bootstrap负责和总配置中心的沟通的,application是仅跟自己沟通的配置文件,也就是先加载bootstrap再加载application`,前者优先级更高

server:
  port: 3355

spring:
  application:
    name: config-client
  cloud:
    #Config客户端配置
    config:
      label: master #分支名称
      name: config #配置文件名称
      profile: dev #读取后缀名称 上诉3个综合就是 master分支上 config-dev.yml
      uri: http://localhost:3344
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

④、主启动

/**
 * @author PengHuAnZhi
 * @createTime 2021/2/16 15:27
 * @projectName SpringCloudDemo
 * @className ConfigClientMain3355.java
 * @description TODO
 */
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain3355 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(ConfigClientMain3355.class, args);
    }
}

⑤、Controller

/**
 * @author PengHuAnZhi
 * @createTime 2021/2/16 15:30
 * @projectName SpringCloudDemo
 * @className ConfigClientController.java
 * @description TODO
 */
@RestController
@Slf4j
public class ConfigClientController {
    
    
    // 因为config仓库以rest形式暴露,所以所有客户端都可以通过config服务端访问到github上对应的文件信息
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo() {
    
    
        return configInfo;
    }
}

⑥、测试

image-20210216153729149

4、客户端动态刷新

①、问题出现

修改远程仓库的dev配置文件

image-20210216155443348

再次访问3344,发现能够实时更新

image-20210216155551020

访问3355,可以发现客户端无论刷新多少次version都是1,当重新启动后,才更新。这对于微服务来说可是噩梦,有些微服务启动一次花费的时间是十分巨大的。

image-20210216155603782

image-20210216155913254

为了避免每次修改配置都需要重启服务,接下来开始配置动态刷新

②、添加POM依赖

前面POM已经添加了,这里是要强调一下,这个jar包是必须的

<!--监控-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

③、修改YML

server:
  port: 3355

spring:
  application:
    name: config-client
  cloud:
    #Config客户端配置
    config:
      label: main #分支名称
      name: config #配置文件名称
      profile: dev #读取后缀名称 上诉3个综合就是 master分支上 config-dev.yml
      uri: http://localhost:3344
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

#暴露监控端点
management:
  endpoints:
    web:
      exposure:
        include: "*"

④、添加注解

Controller上面添加一个@RefreshScope注解

/**
 * @author PengHuAnZhi
 * @createTime 2021/2/16 15:30
 * @projectName SpringCloudDemo
 * @className ConfigClientController.java
 * @description TODO
 */
@RestController
@Slf4j
@RefreshScope
public class ConfigClientController {
    
    
    // 因为config仓库以rest形式暴露,所以所有客户端都可以通过config服务端访问到github上对应的文件信息
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo() {
    
    
        return configInfo;
    }
}

⑤、测试

修改远程仓库,version改为4

image-20210216161133845

访问3344

image-20210216161203535

访问3355,哈哈哈哈,怎么还是3

image-20210216161420473

⑥、手动发送POST请求刷新

还有一步,需要做运维的大哥手动发送一个POST请求给3355来刷新

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

image-20210216161654866

⑦、再次测试

此时我并没有重启3355,再次访问测试一下可不可以更新配置

image-20210216161740395

6、新的问题

我:大哥你改完发个POST请求刷新一下

运维攻城狮:我不,你们那么多微服务,难道要我一个个全部发个POST

我:我们重启微服务很费资源和时间啊,大哥好商量。

运维攻城狮:我TM不干了!

如果微服务过多,修改一次配置就需要每个微服务都发送POST请求刷新一次,这样真的好吗?能否找到类似于广播,一次刷新,处处生效?可以考虑下面的解决方法:

  • 写个for循环
  • 写个自动化脚本,自动执行

但是如果在运行的服务中,假设共有100台,其中有2台因为版本的问题,暂时不需要跟新配置,我们又如何进行精确刷新呢?这就引入了新的组件Bus消息总线

猜你喜欢

转载自blog.csdn.net/qq_43509535/article/details/113825805