Spring Cloud统一配置中心(Config)

参考:https://www.jianshu.com/p/997600098e6c   

        在普通单体应用,我们常使用配置文件(application(*).properties(yml))管理应用的所有配置。这些配置文件在单体应用中非常胜任其角色,并没有让我们感觉到有头疼的地方。但随着微服务框架的引入,微服务数量就会在我们产品中不断增加,之前我们重点考虑的是系统的可伸缩、可扩展性好,但随之就是配置管理的问题就会一一暴露出来。起初微服务器各自管各自的配置,在开发阶段并没什么问题,但到了生产环境管理就会很头疼,如果要大规模更新某项配置,困难就可想而知。

        为此,在分布式系统中,Spring Cloud提供一个Config子项目,该项目核心就是配置中心,通过一个服务端和多个客户端实现配置服务。我们可使用配置服务器集中的管理所有服务的各种环境配置文件。配置服务中心默认采用Git的方式进行存储,因此我们很容易部署修改,并可以对环境配置进行版本管理。Spring Cloud Config具有中心化、版本控制、支持动态更新和语言独立等特性。其特点是:

  • 提供服务端和客户端支持(Spring Cloud Config Server和Spring Cloud Config Client);
  • 集中式管理分布式环境下的应用配置;
  • 基于Spring环境,实现了与Spring应用无缝集成;
  • 可用于任何语言开发的程序;
  • 默认实现基于Git仓库(也支持SVN),从而可以进行配置的版本管理;

Spring Cloud Config的结构图如下:

 

        从图中可以看出Spring Cloud Config有两个角色(类似Eureka): Server和Client。Spring Cloud Config Server作为配置中心的服务端承担如下作用:

  • 拉取配置时更新Git仓库副本,保证是配置为最新;
  • 支持从yml、json、properties等文件加载配置;
  • 配合Eureke可实现服务发现,配合Cloud Bus(这个后面我们在详细说明)可实现配置推送更新;
  • 默认配置存储基于Git仓库(可以切换为SVN),从而支持配置的版本管理.

而对于,Spring Cloud Config Client则非常方便,只需要在启动配置文件中增加使用Config Server上哪个配置文件即可。

构建Config-Server(idea)

pom如下:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

启动类:

@SpringBootApplication
@EnableConfigServer
public class SpringCloundConfigDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloundConfigDemoApplication.class, args);
    }
}

其中增加了@EnableConfigServer。

application.properties:

server.port=8890
spring.application.name=server-config
spring.cloud.config.server.git.uri=https://gitee.com/skyLogin/SpringCloundConfigGit.git
spring.cloud.config.server.git.username=登录名
spring.cloud.config.server.git.password=密码

这里最重要的是需要配置Git仓库的地址及登录用户名和口令。

我们在SpringCloundConfigGit仓库中提交如下文件
user.properties:

project.name = sky

user-dev.properties:

project.description = dev-description

启动测试:

{
    "name": "user",
    "profiles": ["dev"],
    "label": null,
    "version": "9bc698347dcb4e82e1c8fc631d7409cc3f0e6a65",
    "state": null,
    "propertySources": [{
        "name": "https://gitee.com/skyLogin/SpringCloundConfigGit.git/user-dev.properties",
        "source": {
            "project.description": "dev-description"
        }
    }, {
        "name": "https://gitee.com/skyLogin/SpringCloundConfigGit.git/user.properties",
        "source": {
            "project.name": "sky"
        }
    }]
}

        这里可以看到,我们提交到Git中的配置文件已经能够被server-config正确的读取到。
 

构建config-client

        config-client可以是任何一个基于Spring boot的应用,这里为了讲解方便,我们构建一个非常简单的web工程。我们的config-client项目需要引入对spring-cloud-starter-config的依赖,如下:

 

pom:

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

一个标准的Spring Boot启动类:启动类

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

这个测试Controller主要就是验证我们可以从Git仓库中获取配置内容。编写测试Controller

@RestController
public class ConfigController {
    @Value("${project.name}")
    String name;

    @Value("${project.description}")
    String description;
    @RequestMapping("/config/get/message")
    public String getMessage() {
        return name + " - " + description;
    }
}

这里编写的配置文件名称为:bootstrap.properties,内容如下:编写配置文件

server.port=8891

spring.application.name=user
spring.cloud.config.profile=dev
spring.cloud.config.uri= http://localhost:8890/

定义了微服务的名称和profile以及配置服务器的地址。  

注意: 这些配置不能够配置在application.properties文件中,因为在Spring Boot启动时有引导上下文应用上下文的概念,只有将配置服务器信息定义在引导上下文中,才能够从配置服务器中获取到配置信息。否则,服务启动时会报找不到变量定义的错误。

启动测试

说明,我们的config-client已经成功从server-config上获取到配置的数据了。


Config Server配置文件映射关系

Config Server启动以后,我们可以通过它暴露的端点获取配置文件内容,http请求地址与配置文件映射关系如下:

# 映射{application}-{profile}.properties文件
/{application}/{profile}/[{label}]
/{label}/{application}-{profile}.properties
/{application}-{profile}.properties
/{label}/{application}-{profile}.yml
/{application}-{profile}.yml

{application}通常使用微服务名称,对应Git仓库中文件名的前缀;
{profile}对应{application}-后面的dev、pro、test等;
{label}对应Git仓库的分支名,默认为master。

Config Client从Config Server中获取配置数据的流程:

1.Config Client 启动时,根据 bootstrap.properties 中配置的应用名称(application)、环境名(profile)和分支名(label),向 Config Server 请求获取配置数据;
2.Config Server 根据 Config Client 的请求及配置,从Git仓库(这里以Git为例)中查找符合的配置文件;
3.Config Server 将匹配到的Git仓库拉取到本地,并建立本地缓存;
4.Config Server 创建Spring的 ApplicationContext 实例,并根据拉取的配置文件, 填充配置信息,然后将该配置信息返回给 Config Client ;
5.Config Client 获取到 Config Server 返回的配置数据后,将这些配置数据加载到自己的上下文中。同时,因为这些配置数据的优先级高于本地Jar包中的配置,因此将不再加载本地的配置。

那么,Config Server 又是如何与Git仓库中的配置文件进行匹配的呢?通常,我们会为一个项目建立类似如下的配置文件:

mallweb.properties : 基础配置文件;
mallweb-dev.properties : 开发使用的配置文件;
mallweb-test.properties : 测试使用的配置文件;
mallweb-prod.properties : 生产环境使用的配置文件;

当我们访问 Config Server 的端点时,就会按照如下映射关系来匹配相应的配置文件:

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

上面的Url将会映射为格式为:{application}-{profile}.properties(yml)的配置文件。另外, label 则对应Git上分支名称,是一个可选参数,如果没有则为默认的 master 分支。

而 Config-Client 的 bootstrap.properties 配置对应如下:

spring.application.name application;
spring.cloud.config.profile profile;
spring.cloud.config.label label.

Config Server健康状况

Config Server自带了健康状况指示器,暴露的endpoint为/health,用于检查配置的仓库是否可用。对于文中的Config Server,请求http://localhost:8181/health返回如下结果

{
    "status": "UP"
}

配置刷新

Config-Client中提供了一个 refresh 端点来实现配置文件的刷新。要想使用该功能,我们需要在Config-Client的pom.xml文件中增加以下依赖:

    org.springframework.boot
    spring-boot-starter-actuator

这样,当修改配置文件并提交到Git仓库后,就可以使用: http://localhost:8080/refresh 刷新本地的配置数据。但是,最好的方式还是和Spring Cloud Bus进行整合,这样才能实现配置的自动分发,而不是需要手工去刷新配置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章