• 第4章 微服务太多,配置文件怎么维护


    目录

    4.1 初识分布式配置

    4.2 Spring Cloud Config

    4.2.1 Config Server

    4.2.2 Config Client

    4.2.3 配置刷新

    4.3 小结


    在前面有提到,微服务系统是一种典型的分布式系统,我们会将每个功能都尽可能地拆分一个可独立部署、运行的服务,服务部署完成后,每一次请求的完成,都可能涉及到多个服务的协调作业,面对越来越多的微服务,我们需要有一个东西可以方便地管理配置文件、最好可以在一个地方管理所有微服务的配置,这个就是我们接下来要说的分布式配置组件了。在接下来的内容中,简称这个分布式配置组件为配置中心。

    4.1 初识分布式配置

    在开始介绍Spring Cloud的配置中心实现之前,我们可以先回忆下以前我们的系统配置是怎么做的。

    最开始学习的时候,很多东西都是没有配置的,基本上都是硬编码,简单、快速,系统很快构建起来了,可是随着系统的功能越来越复杂,代码量越来越大,很多地方进行硬编码已经不能满足我们的需求,我们需要在不同的环境、不同的场景下通过修改配置项来达到不一样的效果,配置项放在代码里面难找,而且修改起来会很麻烦。

    于是,我们将可能频繁变动的项目提出来放在了xml、properties文件中,方便修改,这个时候修改配置的时候已经不需要再去碰业务代码,只要找到对应的配置文件,修改、打包、重新部署就可以了。这样子看起来已经不错了,但是随着分布式架构逐渐流行,一个一个的集群被搭建起来,这个时候再给每个集群实例搭配一个配置文件,维护的工作量就变得很大了。

    这种情况运维人员一般都有一个config list,记录了每个实例的配置文件放在哪里、叫什么名字、现在的配置项是什么等等。这个清单如果维护出错,对整个系统来说都会是一个灾难。基于这种情况,分布式系统需要一个中心化的配置中心来替代这个config list,并且可以方便地从不同维度来进行配置,最好支持配置项的随时,并且最好能够实时生效。

    4.2 Spring Cloud Config

    Spring Cloud作为一个完善的微服务框架,提供了Spring Cloud Config作为推荐的分布式配置组件。

    Spring Cloud Config提供了服务端和客户端,可以很好地支持分布式系统的配置需求。使用服务端可以快速构建一个独立于业务服务之外的配置中心,配置存储默认使用git,因此它拥有git所拥有的一切优点。同时,它还原生支持使用Spring的Environment和PropertySource来获取配置项。接下来,我们将使用Spring Cloud Config构建一个配置中心。

    4.2.1 Config Server

    新建Spring Boot工程,引入Spring Cloud Config的服务端maven依赖,为了方便测试,我们同时引入了web和actuator的相关依赖。

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</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>        

    pom文件编写完成后,在application.properties中添加配置信息如下:

    spring.application.name=config-server
    server.port=8888
    
    # 配置git仓库地址
    # 这个地址是本书代码所在git仓库地址,这里用到了仓库中的book-config-repo目录
    spring.cloud.config.server.git.uri=https://github.com/hanbin/book
    
    # 配置仓库路径
    spring.cloud.config.server.git.search-paths=book-config-repo
    
    # 去掉git权限校验
    spring.cloud.config.server.git.skip-ssl-validation=true
    
    # 制定远程仓库中配置文件的customer name
    spring.config.name=customer

    最后,在启动类中添加@EnableConfigServer注解开启Spring Cloud Config的服务端功能,然后启动即可。

    我们在book-config-repo目录下新建了配置文件:customer-dev.properties文件。我们可以通过customer-server服务提供的接口来访问这个配置文件。

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

    举例来说,customer-dev.properties中的就是{application}-{profile}.properties的形式,customer即是应用名,profile通常用来标示不同的环境,label在使用git存储时代表的是git的分支,不写则默认为master。

    上面这些URI都可以获取到远程配置,可以看到使用上面格式的地址访问可以看到如下内容:

    http://localhost:8888/customer/dev
    http://localhost:8888/customer/dev/master

    通过上面两个链接可以得到下面的结果:

    {
        "name": "customer",
        "profiles": [
            "dev"
        ],
        "label": "master",
        "version": "97ffd82376b9ba87c5a1ffcf60b67eb4866f2415",
        "state": null,
        "propertySources": [
            {
                "name": "https://github.com/hanbin/book/book-config-repo/customer-dev.properties",
                "source": {
                    "name": "icer123",
                    "age": "1001"
                }
            }
        ]
    }

    通过其他格式接口可以直接获取到的结果都是:

    age: 1001
    name: icer123

    age和name就是我们需要的配置项。

    构建完成配置中心后,接下来我们看看如何将微服务构建成为“配置中心客户端”,来获取配置中心的配置项。

    4.2.2 Config Client

    前面我们创建了customer服务,这节我们会将customer服务作为config-server的client,通过远程获取的方式拿到customer-dev.properties中的配置项。

    在开始之前,这里要提到一个新的endpoint:env。env端点主要用来显示服务的配置信息。在Spring
    Boot2中,env端点默认是关闭的。通过添加下面的代码到application.properties中,可以让env端点能够被访问。

    management.endpoints.web.exposure.include=health,info,env

    在浏览器中可以看到如图4.1所示的页面。

    641684178b7634a02b7f30b7bc56d276.png
    图4.1 通过浏览器查看env端点

    为customer工程添加Spring Cloud Config的支持,需要在pom.xml文件中添加下面的代码。

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

    启动项目,可以在启动日志中看到如图4.2所示的内容。

    846577e69b6587ce46c18004ff2dc0b8.png

    图4.2 微服务启动过程中加载远程配置中心

    可以看到,添加了Spring Cloud Config的依赖后,项目在启动过程中会默认向http://localhost:8888请求远程配置,附带的参数name为项目的spring.application.name,profiles为default,label为null。

    这里的默认配置不能拿到任何信息,因为profiles传的不对,在customer工程的application.properties配置文件中添加。

    spring.cloud.config.uri=http://localhost:8888
    spring.cloud.config.name=customer
    spring.cloud.config.profile=dev

    重新启动程序,可以看到如图4.3所示的启动日志。

    图4.3 自定义config配置后的启动日志

    通过图4.4可以看到现在customer在启动时读取到了之前我们在config server中的配置文件customer-dev.properties。通过本节最开始打开的env端点可以查看,如图4.4所示。

    图4.4 微服务成功读取到远程配置文件

    这里有两个配置文件需要注意下:spring.application.name 和 spring.cloud.config.name。

    spring.application.name一般配置的是微服务的实例名,这个名字是微服务之间调用时候的唯一名称。spring.cloud.config.name配置的是Spring Cloud Config中涉及的application名称,在本节的例子中,对应的就是customer。如果去掉spring.cloud.config.name这个配置项,Spring Cloud Config会使用spring.application.name的配置去配置中心取值。

    注意:充分使用label,profile可以完美达到一套代码部署在多个环境,仅通过在启动参数中修改label和profile就将各个环境进行区分的目的。

    4.2.3 配置刷新

    前面讲的都是在系统启动之前添加配置,那么在系统运行过程中,能否“热刷新”,让配置项在运行期可以被直接改动。

    Spring Cloud Config是支持“热刷新”的,这里需要用到refresh端点。

    还是以customer工程为例。为了方便测试,我们将application.properties中的:

    management.endpoints.web.exposure.include=health,info,env

    换成:

    management.endpoints.web.exposure.include=*

    这样,customer的所有端口就已经全部被放开了。

    我们新建UserController.java文件,文件内容如下:

    package cn.com.hanbinit.customer.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RefreshScope
    @RestController
    public class UserController {
    
        @Value("${name}")
        private String name;
    
        @Value("${age}")
        private Long age;
    
        @GetMapping("/showinfo")
        public String showNameAndAge(){
            return "name: " + name + ", age: " + age;
        }
    
    }

    上面代码中@RefreshScope注解是实现变量热加载的必需配置。@Value可以获取到配置文件以及环境变量中的配置。上面代码中的name和age就分别对应了配置文件中的name和age。showinfo接口返回了@Value获取到的属性值。

    启动项目,访问http://localhost:8001/showinfo接口,可以看到如图4.5的返回。

    图4.5 通过showinfo接口打印配置项的值

    接下来,我们将customer-dev.properties
    中的icer改为icer123,100改为1001,push到远程仓库。通过postman工具调用refresh端点,如图4.6所示。

    图4.6 调用refresh端点,刷新name和age的值


     

    这个时候,刷新showinfo的调用页面,可以看到如图4.7的结果。

    图4.7 调用refresh端点后showinfo接口的返回

    这里,就说明我们的热加载已经成功。

    注意:这种刷新方式仅适用于非初始化对象的情况下,如果配置项需要在系统启动的时候加载并且使用。那么在这里使用refresh端点是不会生效的。配置项即使刷新过去,但是确没有能真正生效。

    截止到这里,我们已经可以通过Spring Cloud Config搭建远程的配置中心,并且可以让微服务获取到配置中心的配置项,且可以通过refresh端点达到热加载的目的。那么能不能实现自动刷新呢?手动调用refresh端点还是比较麻烦的。自动刷新当然是可以的,自动刷新后面有机会再写。

    4.3 小结

    本章我们使用Spring Cloud Config创建了配置中心,并对之前的customer微服务进行了改造,让customer服务可以远程获取到配置中心的配置。

  • 相关阅读:
    19凡路国庆小作业的题解集合(qwq只是我出的题,我会标明出处的)
    一个for打印99乘法表(这是一种实现方式,可以多种方式的)
    采访学长所得
    洛谷P1028 数的计算
    ccf 2019_03_2 二十四点
    ccf 201812-1 小明上学
    洛谷P3387 【模板】缩点
    洛谷P3216 [HNOI2011]数学作业
    洛谷P1471 方差
    HDU 4114 Disney's FastPass
  • 原文地址:https://www.cnblogs.com/hanbin/p/14224669.html
Copyright © 2020-2023  润新知