【Hoxton.SR1版本】Spring Cloud Config服务配置中心

目录

一、简介

二、配置中心服务端搭建

三、配置中心客户端搭建

四、动态刷新配置

五、实现配置中心服务端高可用

六、总结


一、简介

微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。Spring Cloud提供了Config Server来解决这个问题,我们每一个微服务自己带着一个application.yml,上百个配置文件的管理,维护起来非常困难。

在旧版本的Spring Cloud文章,笔者已经对Config配置中心做了较详细的介绍:https://blog.csdn.net/Weixiaohuai/article/details/82759084

https://blog.csdn.net/Weixiaohuai/article/details/82771082;有需要的小伙伴可以扩展进行学习。

  • Spring Cloud Config是什么?

Spring Cloud Config为微服务架构中的微服务提供集中式的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供一个集中化的外部配置。

  • Spring Cloud Config怎么使用?

Spring Cloud Config分为服务端和客户端两部分。

  1. 服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。
  2. 客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息,配置服务器默认采用git来存储配置信息,这样就有利于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。
  • Spring Cloud Config能干嘛?
  1. 集中管理配置文件;
  2. 不同环境不同配置,动态化的配置更新,分环境部署比如dev、test、prod、beta、release;
  3. 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息;
  4. 当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置;
  5. 将配置信息以REST接口的形式暴露;

Spring Cloud Config与GitHub整合配置?

由于Spring Cloud Config默认使用Git来存储配置文件(也有其他方式,比如SVN和本地文件),但最推荐的还是Git,而且使用的是http/https访问的形式。

Spring Cloud Config官网地址:https://docs.spring.io/spring-cloud-config/docs/2.2.4.RELEASE/reference/html/

二、配置中心服务端搭建

【a】Gitee仓库信息初始化

首先,我们需要拉取Gitee配置中心仓库到本地,使用下面的命令即可:

git clone https://gitee.com/weixiaohuai/spring-cloud-config.git

 然后在拉取的仓库文件夹中添加三个配置文件:

  • application-dev.yml
  • application-test.yml
  • application-prod.yml

注意:三个配置文件的内容中只有environment环境这部分的值不同,分别为test、dev、prod,其余都一样。

接着,我们需要将上述三个配置文件推送到远程Gitee仓库中,执行如下命令即可:

 git add .
 git commit -m "新增三个配置文件"
 git push -u origin master

 

然后进入Gitee官网查看配置文件是否提交成功:

可见,三个配置文件已经成功推送到远程仓库中。

【b】新建一个module:【springcloud-config-server3344】

pom.xml:

<?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>springcloud2020</artifactId>
        <groupId>com.wsh.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-config-server3344</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>

【c】主启动类:加上@EnableConfigServer注解

@EnableConfigServer注解主要是开启Spring Cloud Config分布式配置的功能。 

package com.wsh.springcloud;

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

@SpringBootApplication
//服务配置中心注解
@EnableConfigServer
public class ConfigServerServiceApplication3344 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerServiceApplication3344.class, args);
    }
}

【d】application.yml配置文件

server:
  port: 3344
spring:
  application:
    name:  springcloud-config-server  #注册进Eureka服务器的微服务名
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/weixiaohuai/spring-cloud-config.git #Gitee上面的git仓库名字
          #Gitee仓库中配置文件所在的目录
          search-paths:
            - spring-cloud-config
          #访问git仓库的用户名(如果Git仓库为公开仓库,可以不填写用户名和密码,如果是私有仓库需要填写)
#          username:
          #访问git仓库的密码
#          password:
      #读取的分支名称
      label: master
eureka:
  client:
    service-url:
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/   #集群版Eureka注册中心


【d】测试 

接下来我们需要测试一下Config Server配置中心服务端与Gitee仓库是不是连通的,测试一下能够通过配置中心服务端去读取远程仓库中的三个配置文件。

注意:先启动Eureka Server后再启动Config Server,查看官网资料可知,Spring Cloud Config提供了五种访问配置文件的方式:

  1. /{application}/{profile}[/{label}]
  2. /{application}-{profile}.yml
  3. /{label}/{application}-{profile}.yml
  4. /{application}-{profile}.properties
  5. /{label}/{application}-{profile}.properties

根据上面的规则:

(一)、浏览器访问:http://localhost:3344/application/dev/master

(二)、浏览器访问:http://localhost:3344/application-test.yml

 

 (三)、浏览器访问:http://localhost:3344/master/application-dev.yml

 

上图所见,因为git仓库确实存在application-dev.yml配置文件,所以接口成功返回配置文件的内容,但是如果我们访问http://localhost:3344/application/deploy

以上相当于查询Gitee仓库中是否存在application-deploy.yml这个配置文件,如果不存在,返回的propertySources为空,但是也可以验证我们可以从远程Gitee仓库获取配置文件的内容,简单理解就是我们在服务配置中跟Gitee仓库是连通的。 

 经过以上步骤,Spring Cloud Config Server配置中心服务端就算搭建成功了。

三、配置中心客户端搭建

前面已经介绍过Spring Cloud Config配置中心分为服务端和客户端,上面我们已经成功搭建了配置中心服务端的功能,下面我们将搭建客户端这边的功能,以实现客户端读取到远程仓库中的配置信息。

【a】新建一个module【springcloud-config-client3355】,pom.xml中引入config依赖

<?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>springcloud2020</artifactId>
        <groupId>com.wsh.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-config-client3355</artifactId>

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

【b】主启动类

package com.wsh.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

【c】bootstrap.yml,注意不是application.yml

这里大概描述一下两者的区别:

  • application.yml:用户级的资源配置项;
  • bootstrap.yml:系统级的资源配置项,优先级更高;

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

"Bootstrap"属性有高优先级,默认情况下,它们不会被本地配置覆盖。 "Bootstrap Context"和"Applicaiton Context"有着不同的约定,所以新增了一个"bootstrap.yml"文件,保证 "Bootstrap Context"和"Applicaiton Context"配置的分离。

所以,需要将Config  Client客户端模块下的application.yml文件改为bootstrap.yml,因为bootstrap.yml是比application.yml先加载的,bootstrap.yml优先级高于application.yml。 

spring:
  application:
    name: springcloud-config-client
  cloud:
    config:
      uri: http://localhost:3344/   #指定Config Server服务配置中心的地址
      #配置环境
      #dev为开发环境配置文件
      #test为测试环境
      #pro为正式环境
      profile: dev
      label: master  #指定配置文件的分支名称
server:
  port: 3355
eureka:
  client:
    service-url:
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/   #集群版Eureka注册中心

【d】新增测试方法 

package com.wsh.springcloud.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    private static Logger logger = LoggerFactory.getLogger(TestController.class);

    @Value("${config.server.info}")
    String message;

    @RequestMapping("/getPropertyFromConfigServer")
    public String getPropertyFromConfigServer() {
        String msg = "hello, i am " + message + ", i'm come from config server";
        logger.info(msg);
        return msg;
    }

}

【e】 测试

启动config-server以及config-client,浏览器先访问:http://localhost:3344/master/applicaiton-dev.yml

可见,配置中心服务端是正常访问Gitee仓库配置文件的,接着,浏览器访问:http://localhost:3355/getPropertyFromConfigServer

我们可以看到,成功从Gitee远程仓库中获取了application-dev.yml配置文件中的内容,至此,配置中心客户端也搭建成功。

四、动态刷新配置

接下来,我们需要测试一下配置中心是否支持动态刷新的问题。首先,我们需要去Gitee上随便修改其中一个配置文件的内容,这里以修改applicaion.yml文件为例:添加version版本号说明

我们首先通过配置中心服务端来进行访问:http://localhost:3344/master/applicaiton-dev.yml

可以看到,在不用重启配置中心服务端的情况下,我们的Config Server动态去Gitee仓库中获取到了最新的配置文件,那么配置中心的客户端是否也一样呢?我们浏览器访问:http://localhost:3355/getPropertyFromConfigServer

可以看到,在没有重启配置中心客户端的情况下,客户端是不能感知到Gitee仓库中的配置信息发生变化的。那么我们重启一下Config Client试下,继续访问:http://localhost:3355/getPropertyFromConfigServer

我们发现,重启完配置中心客户端后,就能成功获取到最新的配置文件信息。

上面的测试也说明了我们搭建的配置中心存在一个问题:配置文件的动态刷新问题,如何让客户端不用重启也能获取到最新的配置信息?

【a】Config Client客户端添加actuator监控依赖

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

acutator包含了/refresh刷新API,我们可以调用它来实现配置文件的刷新。

【b】修改bootstrap.yml文件,添加暴露端口配置

#暴露监控端点
management:
  endpoints:
    web:
      exposure:
        include: refresh,info,health

【c】TestController类添加@RefreshScope注解

@RefreshScope:如果刷新了bean,那么下一次访问bean(即执行一个方法)时就会创建一个新实例

@RestController
//@RefreshScope注解的作用: 如果刷新了bean,那么下一次访问bean(即执行一个方法)时就会创建一个新实例
@RefreshScope
public class TestController {
    private static Logger logger = LoggerFactory.getLogger(TestController.class);

    @Value("${config.server.info}")
    String message;

    @RequestMapping("/getPropertyFromConfigServer")
    public String getPropertyFromConfigServer() {
        String msg = "hello, i am " + message + ", i'm come from config server";
        logger.info(msg);
        return msg;
    }

}

【d】测试

a、重启config-client,浏览器访问:http://localhost:3355/getPropertyFromConfigServer,可以看到当前的配置值:

b、然后我们修改Gitee仓库配置文件中的值:版本号version修改为3。

c、再次访问一次http://localhost:3355/getPropertyFromConfigServer,可以看到配置文件并没有改变:

d、然后我们修改Gitee仓库配置文件中的值:版本号version修改为4。

d、接着我们通过actuator暴露的接口,发送POST请求发送到http://localhost:3355/actuator/refresh,这时候不能通过浏览器,注意是post请求,否则会报错。这里我们使用postman发送post请求,如下图:

 

 

 

e、我们再次访问http://localhost:3355/getPropertyFromConfigServer,可以看到配置值已经是更新后的值,如下图所示:

 

至此,我们通过actuator实现了手动刷新Gitee远程仓库中的配置文件的内容。

注意一下在config-client项目中的controller上需要加上@RefreshScope注解。

五、实现配置中心服务端高可用

前面我们已经实现了Spring Cloud Config分布式配置中心的功能,我们已经可以通过Config Server获取Gitee远程仓库配置文件中的内容,但是在实际项目中,当服务实例数量比较多的情况下,每个服务单元都从配置中心获取配置信息,假如配置中心由于网络等原因挂掉了,这时候会导致那些服务实例请求失败等一系列问题。这时候可以考虑将配置中心做成一个微服务,注册到Eureka中,这样启动多个Config Server就可以实现负载均衡,从而实现配置中心的高可用。

下面我们将前面搭建的Config Server改造一下:

【a】pom.xml加入如下依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

【b】主启动类加上 @EnableDiscoveryClient:让config-server配置中心成为eureka的服务端,通过负载均衡实现高可用

package com.wsh.springcloud;

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

@SpringBootApplication
//服务配置中心注解
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigServerServiceApplication3344 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerServiceApplication3344.class, args);
    }
}

【c】application.yml修改增加如下配置

eureka:
  client:
    service-url:
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/   #集群版Eureka注册中心

以上配置将配置中心注册到Eureka上,别的服务就可以通过serviceId指定配置中心的地址,从而实现配置中心高可用。

下面是Config Client端的修改:

【a】通过serviceId指定配置中心的地址

spring:
  application:
    name: springcloud-config-client
  cloud:
    config:
      #      uri: http://localhost:3344/   #指定Config Server服务配置中心的地址

      #配置环境
      #dev为开发环境配置文件
      #test为测试环境
      #pro为正式环境
      profile: dev
      label: master  #指定配置文件的分支名称
      discovery:
        enabled: true  #开启通过服务访问config-server的功能
        service-id: springcloud-config-server  #指定Config Server服务注册到Eureka中的微服务名称(即config-server的application-name)
server:
  port: 3355
eureka:
  client:
    service-url:
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/   #集群版Eureka注册中心
  • spring.cloud.config.discovery.enabled:true 表示开启通过服务访问config-server功能
  • spring.cloud.config.discovery.service-id:springcloud-config-server 表示指定配置中心注册到eureka的serviceId(即config-server的application-name)

接下来,我们重启Config Server和Config Client,浏览器访问:http://localhost:3355/getPropertyFromConfigServer

可见, 通过serviceId方式指定也能成功获取到远程仓库中的配置信息,有兴趣的小伙伴可以将Config Server集群部署,然后模拟其中一台发生宕机现象,然后测试一下Config Client是否还能正常获取到配置文件信息。 

六、总结

本文主要介绍了如何搭建Spring Cloud Config配置中心服务端以及客户端,并且实现了高可用的Config Server配置中心以及利用Actuator暴露的refresh接口来实现配置的手动更新。以上相关项目的代码我已经放在Gitee上,有需要的小伙伴可以去拉取进行学习:https://gitee.com/weixiaohuai/springcloud_Hoxton,由于笔者水平有限,如有不对之处,还请小伙伴们指正,相互学习,一起进步。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值