Spring Cloud Config 分布式配置中心简介及使用

1. 分布式配置中心应用场景

往往,我们使用配置文件管理一些配置信息,比如application.yml

  • 单体应用架构,配置信息的管理、维护并不会显得特别麻烦,手动操作就可以,因为就一个工程;
  • 微服务架构,因为我们的分布式集群环境中可能有很多个微服务,我们不可能一个一个去修改配置然后 重启生效,在一定场景下我们还需要在运行期间动态调整配置信息,比如:根据各个微服务的负载情 况,动态调整数据源连接池大小,我们希望配置内容发生变化的时候,微服务可以自动更新。

场景总结如下:

  1. 集中配置管理,一个微服务架构中可能有成百上千个微服务,所以集中配置管理是很重要的(一次 修改、到处生效)
  2. 不同环境不同配置,比如数据源配置在不同环境(开发dev,测试test,生产prod)中是不同的
  3. 运行期间可动态调整。例如,可根据各个微服务的负载情况,动态调整数据源连接池大小等配置,修改后可自动更新
  4. 如配置内容发生变化,微服务可以自动更新配置 那么,我们就需要对配置文件进行集中式管理,这也是分布式配置中心的作用。

2. Spring Cloud Config简介

Spring Cloud Config是一个分布式配置管理方案,包含了 Server端和 Client端两个部分。
在这里插入图片描述

  • Server 端:提供配置文件的存储、以接口的形式将配置文件的内容提供出去,通过使用 @EnableConfigServer注解在 Spring boot 应用中非常简单的嵌入
  • Client 端:通过接口获取配置数据并初始化自己的应用

3. Config分布式配置应用

说明:Config Server是集中式的配置服务,用于集中管理应用程序各个环境下的配置。 默认使用Git存储配置文件内容,也可以SVN。

比如,我们要对“简历微服务”的application.yml进行管理(区分开发环境、测试环境、生产环境)

  1. 登录码云,创建项目cloud-config-demo,项目结构如下
    在这里插入图片描述
  2. 上传yml配置文件,命名规则如下:
    {application}-{profile}.yml 或者 {application}-{profile}.properties
    其中,application为应用名称,profile指的是环境(用于区分开发环境,测试环境、生产环境等)
    示例:lagou-service-resume-dev.yml、lagou-service-resume-test.yml、lagou-service-resume- prod.yml
    lagou-service-resume.properties 内容
lagou.message=test_rpp
mysql.url=jdbc:mysql://localhost:3306/rpp_test?useUnicode=true&characterEncoding=utf8

lagou-service-resume-dev.properties

mysql.username=rpp
  1. 构建Config Server统一配置中心
  • 新建SpringBoot工程,引入依赖坐标(需要注册自己到Eureka)
<dependencies>
    <!--eureka client 客户端依赖引入-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--config配置中心服务端-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-bus-amqp</artifactId>-->
<!--        </dependency>-->
</dependencies>
  • 配置启动类,使用注解@EnableConfigServer开启配置中心服务器功能
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer  // 开启配置中心功能
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class,args);
    }
}
  • application.yml配置
server:
  port: 9006
#注册到Eureka服务中心
eureka:
  client:
    service-url:
      # 注册到集群,就把多个Eurekaserver地址使用逗号连接起来即可;注册到单实例(非集群模式),那就写一个就ok
      defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka
  instance:
    prefer-ip-address: true  #服务实例中显示ip,而不是显示主机名(兼容老的eureka版本)
    # 实例名称
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
spring:
  application:
    name: lagou-cloud-configserver
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/rppzpy/cloud-config-demo.git #配置git服务地址
          username: xxxx #配置git用户名
          password: xxxx #配置git密码
          search-paths:
            - cloud-config-demo
      # 读取分支
      label: master
#  rabbitmq:
#    host: 127.0.0.1
#    port: 5672
#    username: guest
#    password: guest
#针对的被调用方微服务名称,不加就是全局生效
#lagou-service-resume:
#  ribbon:
#    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #负载策略调整
# springboot中暴露健康检查等断点接口
management:
  endpoints:
    web:
      exposure:
        include: "*"
  # 暴露健康接口的细节
  endpoint:
    health:
      show-details: always
  • 测试访问:http://localhost:9006/master/lagou-service-resume-dev.yml,查看到配置文件内容
    在这里插入图片描述
  • 测试访问:http://localhost:9006/master/lagou-service-resume-pro.yml 或者 http://localhost:9006/master/lagou-service-resume.yml
    在这里插入图片描述
  • 测试访问:http://localhost:9006/master/lagou-service-resume-dev.properties
    在这里插入图片描述
    从上面的测试可以看出仓库中的文件是properties格式,通过yml格式依然能访问到,yml或者properties的文件内容都能加载,可以互相转换。
  1. 构建Client客户端(在已有简历微服务基础上)

已有工程中添加依赖坐标

<!--Config 客户端依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-client</artifactId>
</dependency>

application.yml修改为bootstrap.yml配置文件
bootstrap.yml是系统级别的,优先级比application.yml高,应用启动时会检查这个配置文件,在这个 配置文件中指定配置中心的服务地址,会自动拉取所有应用配置并且启用。
(主要是把与统一配置中心连接的配置信息放到bootstrap.yml) 注意:需要统一读取的配置信息,从集中配置中心获取

server:
  port: 8081
spring:
  application:
    name: lagou-service-resume
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/rpp_test?useUnicode=true&characterEncoding=utf8
    username: root
    password: 123456
  jpa:
    database: MySQL
    show-sql: true
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl  #避免将驼峰命名转换为下划线命名
  cloud:
    # config客户端配置,和ConfigServer通信,并告知ConfigServer希望获取的配置信息在哪个文件中
    config:
      name: lagou-service-resume  #配置文件名称
      profile: dev  #后缀名称
      label: master #分支名称
      uri: http://localhost:9006    #ConfigServer配置中心地址
#  rabbitmq:
#    host: 127.0.0.1
#    port: 5672
#    username: guest
#    password: guest
#注册到Eureka服务中心
eureka:
  client:
    service-url:
      # 注册到集群,就把多个Eurekaserver地址使用逗号连接起来即可;注册到单实例(非集群模式),那就写一个就ok
      defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka
  instance:
    prefer-ip-address: true  #服务实例中显示ip,而不是显示主机名(兼容老的eureka版本)
    # 实例名称
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
    # 自定义Eureka元数据
    metadata-map:
      cluster: cl1
      region: rn1
management:
  endpoints:
    web:
      exposure:
        include: "*"
  1. 测试读取配置中心的数据
/**
 * 该类用于模拟,我们要使用共享的那些配置信息做一些事情
 */
@RestController
@RequestMapping("/config")
public class ConfigController {

    // 和取本地配置信息一样
    @Value("${lagou.message}")
    private String lagouMessage;
    @Value("${mysql.url}")
    private String mysqlUrl;


    // 内存级别的配置信息
    // 数据库,redis配置信息

    @GetMapping("/viewconfig")
    public String viewconfig() {
        return "lagouMessage==>" + lagouMessage  + " mysqlUrl=>" + mysqlUrl;
    }
}

访问:http://localhost:8081/config/viewconfig 可以看到成功读取到配置中心的数据

4. Config配置手动刷新

不用重启微服务,只需要手动的做一些其他的操作(访问一个地址/refresh)刷新,之后再访问即可
此时,客户端取到了配置中心的值,但当我们修改GitHub上面的值时,服务端(Config Server)能实时获取最新的值,但客户端(Config Client)读的是缓存,无法实时获取最新值。Spring Cloud已经为 我们解决了这个问题,那就是客户端使用post去触发refresh,获取最新数据。

  1. Client客户端添加依赖springboot-starter-actuator, spring-cloud-config-client 依赖中已经添加该依赖
  2. Client客户端bootstrap.yml中添加配置(暴露通信端点)
# 暴露通信端点
management:
  endpoints:
    web:
      exposure:
        include: "*"
  1. Client客户端使用到配置信息的类上添加@RefreshScope
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {

    // 和取本地配置信息一样
    @Value("${lagou.message}")
    private String lagouMessage;
    @Value("${mysql.url}")
    private String mysqlUrl;

    @GetMapping("/viewconfig")
    public String viewconfig() {
        return "lagouMessage==>" + lagouMessage  + " mysqlUrl=>" + mysqlUrl;
    }
}
  1. 手动向Client客户端发起POST请求,http://localhost:8080/actuator/refresh,刷新配置信息

手动刷新方式避免了服务重启,如果服务比较多,Git配置修改后,可以写个脚本循环手动刷新每个微服务

5. Config配置自动更新

需求:实现一次通知处处生效
在微服务架构中,我们可以结合消息总线(Bus)实现分布式配置的自动更新(Spring Cloud Config+Spring Cloud Bus)

  • 消息总线Bus

所谓消息总线Bus,即我们经常会使用MQ消息代理构建一个共用的Topic,通过这个Topic连接各个微服 务实例,MQ广播的消息会被所有在注册中心的微服务实例监听和消费。换言之就是通过一个主题连接各个微服务,打通脉络。
Spring Cloud Bus(基于MQ的,支持RabbitMq/Kafka) 是Spring Cloud中的消息总线方案,Spring Cloud Config + Spring Cloud Bus 结合可以实现配置信息的自动更新。

  • config+bus实现配置自动更新示意图
    在这里插入图片描述

  • Spring Cloud Config+Spring Cloud Bus 实现自动刷新

MQ消息代理,我们这里选择使用RabbitMQ,ConfigServer和ConfigClient都添加都消息总线的支持以及与RabbitMq的连接信息

  1. Config Server服务端添加消息总线支持,ConfigClient服务消费端(获取配置信息的消费端)同样也需要添加该依赖
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
  1. ConfigServer添加配置,ConfigClient服务消费端(获取配置信息的消费端)同样也需要添加该配置
spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
  1. 配置微服务暴露端口,用于调用接口刷新配置信息
# 暴露通信端点
management:
  endpoints:
    web:
      exposure:
        include: "*"
  1. 刷新配置信息

重启服务,更改配置之后,向配置中心服务端发送post请求 http://localhost:9003/actuator/bus-refresh,各个客户端配置即可自动刷新

在广播模式下实现了一次请求,处处更新,如果我只想定向更新呢?
发起刷新请求地址为:http://localhost:9003/actuator/bus-refresh/lagou-service-resume:8081
即为最后面跟上要定向刷新的实例的 服务名:端口号即可

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值