美文网首页晓我课堂
Spring Cloud系列之配置中心Config

Spring Cloud系列之配置中心Config

作者: wavefreely | 来源:发表于2021-12-23 11:07 被阅读0次

    Spring Cloud系列之Eureka
    Spring Cloud系列之配置中心Config
    Spring Cloud系列之gateway
    Spring Cloud系列之Feign
    Spring Cloud系列之Hystrix
    Spring Cloud系列之链路追踪

    配置中心可以简单的理解为一个服务模块,开发人员或运维人员可以通过界面对配种中心进行配置,下面相关的微服务连接到配置中心上面就可以实时连接获取到配置中心上面修改的参数。更新的方式一般有两种

    • pull模式,服务定时去拉取配置中心的数据

    • push模式,服务一直连接到配置中心上,一旦配置有变成,配种中心将把变更的参数推送到对应的微服务上

    这两种做法其实各有利弊

    • pull可以保证一定可以拉取得到数据,pull一般采用定时拉取的方式,即使某一次出现网络没有拉取得到数据,那在下一次定时器也将可以拉取得到数据,最终保证能更新得到配置

    • push也有好处,避免pull定时器获取存在时延,基本可以做到准实时的更新,但push也存在问题,如果有网络抖动,某一次push没有推送成功,将丢失这次配置的更新

    目前比较流行的配种中心开源组件有Spring Cloud Config,百度的disconf,阿里的Nacos,还有携程的apollo。

    实现原理大同小异

    配置中心.png

    实践

    config server搭建
    • 引入依赖
    <?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>dy-springcloud</artifactId>
            <groupId>com.dy</groupId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.dy</groupId>
        <artifactId>config-server</artifactId>
    
        <dependencies>
    
            <!--config server端依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-config-server</artifactId>
            </dependency>
    
            <!--config server端也注册到注册中心-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
        </dependencies>
    
    </project>
    
    • 配置文件
    #eureka 参数配置
    eureka:
      # 此实例注册到eureka服务端的唯一的实例ID,其组成为${spring.application.name}:${spring.application.instance_id:${random.value}}
      instance:
        #  与此实例相关联的主机名,是其他实例可以用来进行请求的准确名称
        hostname: localhost
        # 获取实例的ip地址
        prefer-ip-address: true
        #  eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒
        lease-renewal-interval-in-seconds: 10
        #  Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒
        lease-expiration-duration-in-seconds: 30
      client:
        # 注册自己
        register-with-eureka: true
        # 是否拉取服务
        fetch-registry: true
        # 配置注册中心服务地址
        service-url:
          # eureka 服务地址
          defaultZone: http://172.16.10.16:10001/eureka
    server:
      port: 10002
    spring:
      application:
        name: config-server
      cloud:
        # cloud配置中心相关配置
        config:
          server:
            # git相关配置
            git:
              # git 地址
              uri: https://gitee.com/dai-yong-1/config-server-dy.git
              # git用户名
              username: xxxx
              # git密码
              password: xxxxx
              # 配置文件所在文件夹
              search-paths: config-yml
    

    配置中心git仓库如下:

    配置中心git仓库.png
    • 启动类
    /**
     * @Description:
     * @author: dy
     */
    @EnableConfigServer  //声明当前应用是config server服务
    @EnableDiscoveryClient //开启Eureka客户端发现功能
    @SpringBootApplication
    public class ConfigServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConfigServerApplication.class, args);
        }
    
    }
    
    config client 搭建
    • 引入依赖
    <dependencies>
    
        <!--配置中心相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
    
        <!--erueka客户端相关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    
    </dependencies>
    
    • 配置类
    server:
      port: 11001
    spring:
      application:
        name: user-service
      cloud:
        config:
          enabled: true
          # 与远程仓库中的配置文件的application保持一致
          name: user-service
          # 远程仓库中的配置文件的profile保持一致
          profile: dev
          # 远程仓库中的 分支 版本保持一致
          label: master
          # config server地址
          uri: http://localhost:10002/
          # 配置的用户名密码
          username: root
          password: root
    

    在git仓库里面我们新建了一个配置文件user-service-dev.yml,配置内容如下:

    dy:
      config:
        app-id: 110
        app-name: 'user-service-name'
    

    使用的时候在config client端我们新建一个配置文件:

    package com.dy.user.config;
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Component;
    
    /**
     * @Description:
     * @author: dy
     */
    @Data
    @Component
    @Configuration
    @ConfigurationProperties(prefix = "dy.config")
    public class AppInfo {
    
        private String appId;
    
        private String appName;
    
    }
    

    测试类如下:

    package com.dy.user.resource;
    
    import com.dy.user.client.UserClient;
    import com.dy.user.config.AppInfo;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @Description:
     * @author: dy
     */
    @Slf4j
    @RestController
    @RequestMapping(UserClient.MAPPING)
    public class UserResource implements UserClient {
    
        @Autowired
        private AppInfo appinfo;
    
        @Override
        public String getUserId() {
            return "======111111222>>"+appinfo.getAppId();
        }
    }
    

    运行结果如下:

    配置中心运行结果.png

    如此我们就大致实现了配置中心的基础功能

    config刷新功能

    但是如果我们线上实时修改了git仓库里面的配置文件内容,那我们的客户端怎么及时读取git仓库里面实时的文件内容呢?

    spring cloud config给我们提供了两种方式:

    • config配置手动刷新

    • 自动刷新

    config配置手动刷新
    • 引入依赖
    <!-- 健康监测依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    • 添加配置
    management:
      #启用监控 默认打开health和info,* 表示开放所有端口
      endpoints:
        web:
          exposure:
            include: *
      #打印健康信息详情
      endpoint:
        health:
          show-details: always
    
    • 引用类里面添加注解@RefreshScope

      该注解处代理的bean会在调用/refresh接口时被清空

    @Slf4j
    @RestController
    @RequestMapping(UserClient.MAPPING)
    @RefreshScope
    public class UserResource implements UserClient {
    
        @Autowired
        private AppInfo appinfo;
    
        @Override
        public String getUserId() {
            log.info("==============请求来了===============");
            return "======111111222>>"+appinfo.getAppId();
        }
    }
    

    虽然手动刷新可以避免我们重启服务,但是每次去刷脚本跑接口刷新每个服务感觉十分不便,那有什么更好的方式呢?

    config自动刷新

    在微服务架构体系中,我们可以接口消息总线bus实现配置的自动更新,也就是Spring Cloud Config+Spring Cloud Bus

    Spring Cloud Bus是基于MQ的,支持Rabbitmq/Kafka,是Spring Cloud的消息总线方案。

    具体实现流程如下:

    配置中心自动刷新流程.png

    具体实现如下(mq我们使用的是Rabbitmq):

    config server端

    • 引入依赖
    <!-- spring cloud bus消息总线依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bus-amqp</artifactId>
    </dependency>
    
    • 添加配置
    server:
      port: 10002
    spring:
      application:
        name: config-server
      # 这里我们用的rabbitmq
      rabbitmq:
        addresses: amqp://192.168.2.56:5672
        username: sxw_demo
        password: sxw_demo
      cloud:
        # cloud配置中心相关配置
        config:
          server:
            # git相关配置
            git:
              # git 地址
              uri: https://gitee.com/dai-yong-1/config-server-dy.git
              # git用户名
              username: 15828101225
              # git密码
              password: hd961740841
              # 配置文件所在文件夹
              search-paths: config-yml
              
    #eureka 参数配置  
    eureka:
      # 此实例注册到eureka服务端的唯一的实例ID,其组成为${spring.application.name}:${spring.application.instance_id:${random.value}}
      instance:
        #  与此实例相关联的主机名,是其他实例可以用来进行请求的准确名称
        hostname: localhost
        # 获取实例的ip地址
        prefer-ip-address: true
        #  eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒
        lease-renewal-interval-in-seconds: 10
        #  Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒
        lease-expiration-duration-in-seconds: 30
      client:
        # 注册自己
        register-with-eureka: true
        # 不拉取服务
        fetch-registry: true
        # 配置服务地址
        service-url:
          # eureka 服务地址,如果是集群的话;需要指定其它集群eureka地址  ,如果是多台eureka server 地址以逗号隔开
          defaultZone: http://172.16.10.16:10001/eureka
    
    management:
      #启用监控 默认打开health和info,* 表示开放所有端口
      endpoints:
        web:
          exposure:
            include: "*"
      #打印健康信息详情,
      endpoint:
        health:
          show-details: always
    

    config client端

    • 引入依赖
    <!-- spring cloud bus消息总线依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bus-amqp</artifactId>
    </dependency>
    
    • 添加配置
    server:
      port: 11001
    spring:
      application:
        name: user-service
      rabbitmq:
        addresses: amqp://192.168.2.56:5672
        username: sxw_demo
        password: sxw_demo
      zipkin:
        # zipkin server的请求地址
        base-url: http://localhost:10005/
        sender:
          #web 客户端将踪迹日志数据通过网络请求http的方式发送到服务端
          #rabbit 客户端将踪迹日志数据通过mp  rabbit的方式发送到服务端
          #kafka 客户端将踪迹日志数据通过mp  kafka的方式发送到服务端
          type: web
      sleuth:
        sampler:
          probability: 1 # 采样率
      cloud:
        config:
          enabled: true
          # 与远程仓库中的配置文件的application保持一致
          name: user-service
          # 远程仓库中的配置文件的profile保持一致
          profile: dev
          # 远程仓库中的 分支 版本保持一致
          label: master
          # config server地址
          uri: http://localhost:10002/
          # 配置的用户名密码
          username: root
          password: root
    

    运行项目操作步骤如下:

    如果要实现修改完远程git文件自动刷新配置的话,可以在git上面添加一个WebHooks, URL需要把本地的 http://localhost:10002/actuator/bus-refresh映射成公网IP.可以使用第三方内网穿透实现.具体如下:

    配置中心wehooks配置.png

    相关文章

      网友评论

        本文标题:Spring Cloud系列之配置中心Config

        本文链接:https://www.haomeiwen.com/subject/aadhqrtx.html