原 荐 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

前言

上一章节,简单介绍了分布式配置中心 Spring Cloud Config 的使用。同时,我们也遗漏了一些问题,比如如何配置实时生效,当服务端地址变更或者集群部署时,如何指定服务端地址?回想,在服务注册章节,服务提供者和服务消费者,同时往注册中心进行注册和获取服务地址,而本身注册中心又支持高可用配置。所以,对于配置中心,我们也可以将 Server端Client端 往注册中心进行注册,借此实现配置中心的服务化,无需指定具体的ip地址,直接根据服务名称进行调用。

前言

关于高可用

将配置中心服务化,本身是为了实现高可用。而实现高可用的手段是很多的,最常用的就是 负载均衡 。客户端不直连服务端,而是访问 负载均衡 服务,由 负载均衡 来动态选择需要访问的服务端。只是 Spring Cloud Config 天然的就能进行服务化配置,所以,实际中可以根据实际的业务需求来进行合理化抉择的。

原 荐 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

其次,对于使用了 git 或者 svn 作为存储方式时,本身配置仓库的高可用也是一个需要考虑的事项。本身如 github 或者 这些第三方 git 仓库而言,已经实现了高可用了。但一般上部署的微服务都是内网服务,所以一般上是使用如 gitlab 开源git 仓库管理系统进行自建,此时就需要考虑本身仓库的高可用了。

注意:本身教程为了不混淆各知识点,所以都是独立项目进行实例,而不是在原工程上进行修改。 本章节教程采用了多模块工程进行构建实例。父类项目名为: spring-cloud-config-ha 。同时创建服务化的配置文件: my-config-client-ha-dev.propertiesmy-config-client-ha-test.properties

my-config-client-ha-dev.properties

config=this is dev!

my-config-client-ha-dev.properties

config=this is test!

Server端

创建子工程: spring-cloud-confg-ha-server 0.加入pom依赖。

<!-- config server 依赖 -->
        <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>

1.配置文件加入注册中心相关配置。

spring.application.name=spring-cloud-config-ha-server
server.port=15678

#配置文件git配置
spring.cloud.config.server.git.uri=https://github.com/xie19900123/spring-cloud-learning.git
# 搜索路径,即配置文件的目录,可配置多个,逗号分隔。默认为根目录。
spring.cloud.config.server.git.searchPaths=spring-cloud-config-repo
# git用户名和密码 针对私有仓库而言需要填写
spring.cloud.config.server.git.username=
spring.cloud.config.server.git.password=

#添加注册中心配置
# 注册中心地址 -此为单机模式
eureka.client.service-url.defaultZone=http://127.0.0.1:1000/eureka
# 启用ip配置 这样在注册中心列表中看见的是以ip+端口呈现的
eureka.instance.prefer-ip-address=true
# 实例名称  最后呈现地址:ip:15678
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}

2.启动类加入 @EnableDiscoveryClient@EnableConfigServer ,前者开启服务发现功能,后者声明一个 config server

/**
 * config server 服务化
 * 
 * @author oKong
 *
 */
@SpringBootApplication
@EnableConfigServer
//注意这里也可使用@EnableEurekaClient
//但由于springcloud是灵活的,注册中心支持eureka、consulzookeeper等
//若写了具体的注册中心注解,则当替换成其他注册中心时,又需要替换成对应的注解了。
//所以 直接使用@EnableDiscoveryClient 启动发现。
//这样在替换注册中心时,只需要替换相关依赖即可。
@EnableDiscoveryClient
@Slf4j
public class ConfigServerHaApplication {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(ConfigServerHaApplication.class, args);
        log.info("spring-cloud-config-ha-server启动!");
    }
}

关于 Eureka 相关知识点,可以查看:《 第二章:服务注册与发现(Eureka)-上 》和《 第三章:服务注册与发现(Eureka)-下 》,这里就不加以阐述了。

3.启动应用,同时启动 Eureka 服务端。访问下 Eureka 服务端地址: http://127.0.0.1:1000/ ,可以看见服务注册成功了。

原 荐 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

访问: http://127.0.0.1:15678/my-config-client-ha-dev.properties 可以看见配置信息了。

原 荐 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

Client端

创建子工程: spring-cloud-confg-ha-client 0.加入pom依赖。

<!-- config client 依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</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-web</artifactId>
        </dependency>

1.配置文件修改, bootstrap.properties 添加注册中心配置。 bootstrap.properties

# 设置分支
spring.cloud.config.label=master
# 环境变量
spring.cloud.config.profile=dev
# 是否使用注册中心方式进行获取
spring.cloud.config.discovery.enabled=true
# 服务端地址 
# 在不使用注册中心模式下 直接填写实际地址
#spring.cloud.config.uri=http://127.0.0.1:5678
# 注册中心应用id
spring.cloud.config.discovery.service-id=spring-cloud-config-ha-server

#添加注册中心配置
# 注册中心地址 -此为单机模式
eureka.client.service-url.defaultZone=http://127.0.0.1:1000/eureka
# 启用ip配置 这样在注册中心列表中看见的是以ip+端口呈现的
eureka.instance.prefer-ip-address=true
# 实例名称  最后呈现地址:ip:15678
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}

application.properties

# 设置应用名称,需要和配置文件匹配
spring.application.name=my-config-client-ha
server.port=15666

注意:注册中心的相关配置需要放在 bootstrap.properties 中,这样才能利用注册中心进行服务端服务地址获取。

2.启动类,加入 @EnableDiscoveryClient ,开启服务发现功能。

/**
 * 服务化方式调用config server
 * 
 * @author oKong
 *
 */
@SpringBootApplication
@EnableDiscoveryClient
@Slf4j
public class ConfigClientHaApplication {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(ConfigClientHaApplication.class, args);
        log.info("spring-cloud-config-ha-client启动!");
    }

}

3.创建控制层,测试配置参数

/**
 * config client 简单示例
 * @author oKong
 *
 */
@RestController
public class DemoController {

    @Value("${config}")
    String config;
    
    @GetMapping("/")
    public String demo() {
        return "返回的config参数值为:" + config;
    }
}

4.启动应用。一般上应用能启动成功,就说明服务化已经成功了。 启动时,可以看见已经往注册中心去获取服务端地址了。

2018-10-10 23:15:15.302  INFO 26412 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://192.168.2.102:15678/
2018-10-10 23:15:20.728  INFO 26412 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=my-config-client-ha, profiles=[dev], label=master, version=f2645253a37db433d806914b1d04d6aba428831c, state=null

此时,我们访问: http://127.0.0.1:15666/ ,即可看见配置信息返回了。

原 荐 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

refresh实现刷新

在默认情况下,客户端是不会自动感知配置的变化的。此时,我们可以使用 /refresh 端点来进行配置更新。 现在,我们改造下客户端。 0.加入端点依赖。

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

1.修改下变量使用类,加入 @RefreshScope 注解,标记在访问 /refresh 时,进行变量的更新操作。

/**
 * config client 简单示例
 * @author oKong
 *
 */
@RestController
@RefreshScope//使用该注解的类,会在接到SpringCloud配置中心配置刷新的时候,自动将新的配置更新到该类对应的字段中。
public class DemoController {

    @Value("${config}")
    String config;
    
    @GetMapping("/")
    public String demo() {
        return "返回的config参数值为:" + config;
    }
}

重点就是注解 @RefreshScope 了。 2.配置文件开启端点 refresh 。这里需要注意, 2.0 之后,默认只开启了端点 infohealth 。其他的需要通过 management.endpoints.web.exposure.include 进行额外配置。

#开启监控端点
management.endpoints.web.exposure.include=refresh

3.启动应用,此时,动态修改下远程仓库的参数值为: config=this is dev refresh!!! , 使用 Postman 使用 POST 访问: http://127.0.0.1:15666/actuator/refresh

原 荐 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

返回值即为有变动的参数值。

再次访问: http://127.0.0.1:15666/ 可以看见已经是最新的配置参数值了。

原 荐 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

参考资料

  1. https://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#_spring_cloud_config

  2. https://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#refresh-scope

总结

本章节主要讲解了如何将配置中心注册为一个服务,客户端像普通的服务消费者一样,根据服务名即可获取服务端地址,进而进行参数的获取。同时讲解了当属性参数有变时,客户端如何进行感知变化进行参数动态更新。大家应该可以想到,当我们客户端越来越多时,一个个去执行 refresh 时不太现实的,虽然我们可以通过类似 webhook 功能当有提交记录时,主动去触发各客户端的 refresh 方法,在前期项目比较少的情况下,不失为一个好方法, 只需要维护一份待更新的客户端地址列表即可 。但当服务越来越多时,维护此列表也是令人头疼的。此时,我们可以使用 Spring cloud bus 消息总线进行通知。由于目前 Spring cloud bus 知识点尚未开始讲解,同时作者也比较少使用消息总线,所以待查阅相关之后介绍 Spring Cloud bus 章节时,再来进行讲解如何使用 消息总线 进行全自动的配置更新操作。

最后

目前互联网上大佬都有分享 SpringCloud 系列教程,内容可能会类似,望多多包涵了。 原创不易,码字不易 ,还希望大家多多支持。若文中有错误之处,还望提出,谢谢。

老生常谈

499452441
lqdevOps

原 荐 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

个人博客: http://blog.lqdev.cn

源码示例: https://github.com/xie19900123/spring-cloud-learning

原文地址: http://blog.lqdev.cn/2018/10/11/SpringCloud/chapter-eight/

原文 

https://my.oschina.net/xiedeshou/blog/2243313

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 原 荐 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址