Config配置中心

  在分布式系统中,每个服务都有一个单独的配置,服务增多的情况下,配置文件会变得非常多,维护配置文件比较麻烦。所以需要一套集中的、动态的配置管理设施是必不可少的。

  Springcloud提供了一个ConfigServer来解决这个问题。

1.Config简介

1.是什么

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

 

 

   其结构如上图。所有的配置中心在git上维护配置文,本地config服务与git上一致,然后客户端从config服务获取自己需要的配置。

2.结构

  springcloud config分为server端和client端。配置服务器默认采用git来存储配置信息,这样有助于对环境配置进行版本管理,并且可以通过git客户端来方便的管理和访问配置内容。

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

  客户端则是通过指定的配置中心来管理资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。

3.主要作用

1.集中管理配置文件

2.不同环境不同配置,动态化的配置更新,分环境部署,比如dev\test\prod\beta\release

3.运行期间动态调整,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息。

4.当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置

5.将配置信息以REST接口的形式暴露

2.使用

1.github搭建配置文件项目

master分支和dev分支各有三个文件,如下:

(1)master/config-dev.yml

config:
  info: master-dev,版本:1

(2)master/config-prod.yml

config:
  info: master-prod,版本:1

(3)master/config-test.yml

config:
  info: master-test,版本:1

(4)dev/config-dev.yml

config:
  info: dev-dev,版本:1

(5)dev/config-prod.yml

config:
  info: dev-prod,版本:1

(6)dev/config-test.yml

config:
  info: dev-test,版本:1

2.新建cloud-config-center-3344子模块

1.新建moudle

2.修改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>cloud</artifactId>
        <groupId>cn.qz.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-config-center-3344</artifactId>

    <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>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

3.修改yml

server:
  port: 3344

spring:
  application:
    name:  cloud-config-center #注册进Eureka服务器的微服务名
  cloud:
    config:
      server:
        git:
          uri: https://github.com/qiao-zhi/springcloud-config.git #GitHub上面的git仓库名字
        ####搜索目录
          search-paths:
            - springcloud-config
#            默认的分支,如果不配置的话默认是master分支
#          default-label: dev
#          username: 公有的不需要账号密码
#          password: 公有的不需要账号密码
      ####读取分支
      label: master

#服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

4.主启动类:

package cn.qz.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

/**
 * @Author: qlq
 * @Description
 * @Date: 22:44 2020/10/21
 */
@SpringBootApplication
@EnableConfigServer
public class ConfigCenterMain3344 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigCenterMain3344.class, args);
    }
}

5.启动后访问测试:默认读取的是master分支,可以修改。

hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master)
$ curl -X GET http://localhost:3344/config-prod.yml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    41  100    41    0     0     10      0  0:00:04  0:00:03  0:00:01    10config:
  info: master-prod,版本:1


hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master)
$ curl -X GET http://localhost:3344/master/config-prod.yml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    41  100    41    0     0     25      0  0:00:01  0:00:01 --:--:--    25config:
  info: master-prod,版本:1


hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master)
$ curl -X GET http://localhost:3344/dev/config-prod.yml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    38  100    38    0     0     33      0  0:00:01  0:00:01 --:--:--    33config:
  info: dev-prod,版本:1

补充:springcloud有一套自己的访问规则,如下:

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

{application} 就是应用名称,对应到配置文件上来,就是配置文件的名称部分。比如对应config。

{profile} 就是配置文件的版本,我们的项目有开发版本、测试环境版本、生产环境版本,dev、prod、test等。

{label} 表示 git 分支,默认是 master 分支,如果项目是以分支做区分也是可以的,那就可以通过不同的 label 来控制访问不同的配置文件了。

例如:以/{application}/{profile}[/{label}]方式访问:

hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master)
$ curl -X GET http://localhost:3344/config/prod
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   266    0   266    0     0    200      0 --:--:--  0:00:01 --:--:--   200{"name":"config","profiles":["prod"],"label":null,"version":"9fbb23c5f96fb32a9a99ee5c10480abd443f9ab0","state":null,"propertySources":[{"name":"https://github.com/qiao-zhi/springcloud-config.git/config-prod.yml","source":{"config.info":"master-prod,版本:1"}}]}

hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master)
$ curl -X GET http://localhost:3344/config/prod/dev
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   264    0   264    0     0    234      0 --:--:--  0:00:01 --:--:--   234{"name":"config","profiles":["prod"],"label":"dev","version":"24102d09cce20c48fafac63445624ec1b8c2b433","state":null,"propertySources":[{"name":"https://github.com/qiao-zhi/springcloud-config.git/config-prod.yml","source":{"config.info":"dev-prod,版本:1"}}]}

3.建立cloud-config-client-3355项目

  该模块从上面3344服务端拿取自己的配置文件。

1.新建子模块

 

2.修改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>cloud</artifactId>
        <groupId>cn.qz.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-config-client-3355</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!--引入自己抽取的工具包-->
        <dependency>
            <groupId>cn.qz.cloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</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-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

3.新建bootstrap.yml

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://localhost:7001/eureka/

补充:bootstrap.yml和application.yml的区别

  applicaiton.yml是用户级的资源配置项,bootstrap.yml是系统级的,优先级更高。

  Springcloud会创建一个"Bootstrap Context",作为Spring应用的"Application Context"的上下文。初始化的时候,BootstrapContext负责从外部源加载配置属性并解析配置。这两个上下文共享一个外部的Environment。

  bootstrap.yml通常用于“使用Spring Cloud Config Server时,应在bootstrap.yml中指定spring.application.name和spring.cloud.config.server.git.uri”以及一些加密/解密信息。例如,当使用Spring Cloud时,通常从服务器加载“real”配置数据。为了获取URL(和其他连接配置,如密码等),您需要一个较早的或“bootstrap”配置。因此,您将配置服务器属性放在bootstrap.yml中,该属性用于加载实际配置数据(通常覆盖application.yml [如果存在]中的内容)。

  另外,由于application.yml后加载,所以如果有相同属性的情况下,会以application.yml的为准。而且两个文件可以用${varname}互相取文件中的变量。

 4.新建主启动类:

package cn.qz.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain3355 {

    public static void main(String[] args) {
        SpringApplication.run(ConfigClientMain3355.class, args);
    }
}

5.新建controller

package cn.qz.cloud.controller;

import cn.qz.cloud.utils.JSONResultUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigClientController {

    @Value("${config.info}")
    private String configInfo;

    @Value("${server.port}")
    private String serverPort;

    @GetMapping("/configInfo")
    public JSONResultUtil<String> configInfo() {
        String result = "serverPort: " + serverPort + ";configInfo: " + configInfo;
        return JSONResultUtil.successWithData(result);
    }
}

6.测试

liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl http://localhost:3355/configInfo
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   100    0   100    0     0   3225      0 --:--:-- --:--:-- --:--:--  6666{          "success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: maste          r-dev,版本:1"}

liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl http://localhost:3344/config-dev.yml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    40  100    40    0     0      2      0  0:00:20  0:00:17  0:00:03    10config:
  info: master-dev,版本:1

3.存在的问题

  git上修改配置之后,都不重启服务的情况下。3344server可以及时更新,3355客户端不能及时更新

1.上面从github上面修改master/config-dev.yml

config:
  info: master-dev,版本:2

2.测试:

liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl http://localhost:3344/config-dev.yml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    40  100    40    0     0      2      0  0:00:20  0:00:18  0:00:02    10config:
  info: master-dev,版本:2


liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl http://localhost:3355/configInfo
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   100    0   100    0     0   3225      0 --:--:-- --:--:-- --:--:--   97k{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:1"}

  发现3344可以及时更新,3355只有重启之后才可以更新。

3.解决办法:通过配置可以手动触发刷新

(1)修改bootstrap.yml

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://localhost:7001/eureka/

# 暴露监控端点(可以暴露健康状态等,这里暴露所有)
management:
  endpoints:
    web:
      exposure:
        include: "*"

(2)修改Controller,增加@RefreshScope注解

(3)重启之后查看:

liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl http://localhost:3355/configInfo
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   100    0   100    0     0    917      0 --:--:-- --:--:-- --:--:--  1063{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:2"}

(4)git上面修改config-dev.yml

liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl http://localhost:3355/configInfo
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   100    0   100    0     0    917      0 --:--:-- --:--:-- --:--:--  1063{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:2"}

(5)查看3344和3355配置

liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl http://localhost:3344/config-dev.yml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    40  100    40    0     0      1      0  0:00:40  0:00:21  0:00:19    12config:
  info: master-dev,版本:3


liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl http://localhost:3355/configInfo
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   100    0   100    0     0   3225      0 --:--:-- --:--:-- --:--:--  6250{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:2"}

  发现3355还是没有自动同步

(6)手动访问URL触发更新

liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl -X POST http://localhost:3355/actuator/refresh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    39    0    39    0     0      0      0 --:--:--  0:00:43 --:--:--    11["config.client.version","config.info"]

liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master)
$ curl http://localhost:3355/configInfo
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   100    0   100    0     0   3225      0 --:--:-- --:--:-- --:--:--  6666{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:3"}

 

  通过上面的设置,改动完git上配置之后需要手动通过post请求通知服务刷新配置。当然如果服务增多的情况可以通过批处理脚本批量通知。

  仍然不是一个较好的解决方案,因此需要引入springcloud Bus消息总线。

 

posted @ 2020-10-22 21:53  QiaoZhi  阅读(731)  评论(0编辑  收藏  举报