美文网首页
分布式配置中心的实现

分布式配置中心的实现

作者: 漂泊_abc8 | 来源:发表于2019-01-23 15:13 被阅读0次

    一、为什么要用分布式配置中心?

    1.不方便管理和维护
    配置文件都耦合在代码中,和应用一起打包,更改配置需要重新打包或重启
    2.安全性
    这一点主要是针对生产环境的配置来讲的,生产环境的数据库账号密码直接暴露给开发人员,增加了一定的风险

    二、springcloud分布式配置中心架构图

    三、ConfigServer的实现

    从上图可以看出,Spirngcloud config的实现分为两部分,一部分是ConfigServer,其实也是一个注册中心的实例,另外一部分是Config Client ,ConfigServer主要负责管理配置,这里我们来实现一下ConfigServer
    1.maven依赖

    <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>
    

    2.启动类加上@EnableConfigServer注解

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

    3.配置文件

    server:
      port: 8888
    spring:
      application:
        name: config-server
      cloud:
        config:
          server:
            git:
              uri: ...
              username: ...
              password: ...
    eureka:
      client:
        service-url:
          default-zone: http://localhost:8761/eureka
    

    4.如何访问
    注意了,前提是你必须要在git仓库中先建立一个仓库,然后配置两个配置,一个开发dev,一个测试test 如下图:


    这里演示dev和test配置文件的内容以示区别只是端口号不一样,可自行根据具体情况写入配置
    configClient-dev.yml

    configClient-test.yml

    然后我们启动configServer,访问http://localhost:8888/configClient-dev.yml

    这里不一定非是.yml,我们使用.json或者.properties也是可以访问到的,configServer首先读取git中的配置文件,然后用户根据指定的格式可以访问到不同格式的配置文件用于显示

    配置命名的约定规则:
    如:
    1./order-dev.yml (/文件名-环境名.文件后缀)
    2./dev/order-dev.yml (/分支名/文件名-环境名.文件后缀)默认访问master分支,上面demo中git仓该项目只有一个分支,也就是master分支
    每一种都可以用
    /{name}-{profiles}.yml
    /{label}/{name}-{profiles}.yml
    name 服务名
    profile 环境
    label 分支 branch
    5.本地分支指定目录
    configServer在读取远程git的时候会在本地新拉一个分支,观察configServer日志可以看到本地创建了一个目录,那么考虑到服务器文件的安全性,很多时候我们往往需要指定对应的目录用于存放配置,如何实现呢?



    使用basedir指定本地分支存放的文件夹

    server:
      port: 8888
    spring:
      application:
        name: config-server
      cloud:
        config:
          server:
            git:
              uri: #git仓uri
              username: #你的账号
              password: #密码
              basedir: #通过basedir指定本地分支存放的文件夹
    eureka:
      client:
        service-url:
          default-zone: http://localhost:8761/eureka
    

    四、ConfigClient的实现

    1.maven依赖

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

    2.bootstrap.yml
    注意,这里用bootstrap.yml做启动,因为bootstrap.yml是比application.yml先加载的。bootstrap.yml优先级高于application.yml。这里要保证指定ConfigServer的一些配置要先加载,不然它怎么知道去哪里找其他的配置呢?

    spring:
      application:
        # 服务名,也是对应git上配置文件的名字
        name: configClient
      cloud:
        config:
          discovery:
            # ConfigServer的服务名
            service-id: config-server
            enabled: true
          # 指定读取哪个环境的配置文件
          profile: test
    #注意eureka的配置也要放在这里
    eureka:
      client:
        service-url:
          default-zone: http://localhost:8761/eureka
    

    3.启动ConfigClient
    这里我们为了方便演示,git中dev和test配置文件如下


    在启动类上加上如下方法:

    @SpringBootApplication
    @EnableEurekaClient
    @RestController
    public class ConfigClientApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConfigClientApplication.class, args);
        }
    
        @Value("${person.name}")
        private String name;
    
        @Value("${person.age}")
        private Integer age;
    
        @GetMapping("/print")
        public String print(){
            return "name:" + name +",age:" + age;
        }
    }
    

    然后启动访问,因为我们之前配置文件指定的是test环境,可以从日志上看到8082端口启动了,说明读取的也是configClient-test.yml,为了验证我们的结论,访问一下http://localhost:8082/print


    至此,ConfigClient已实现成功读取远程配置

    五、使用spring cloud bus动态刷新配置

    我们讲git中configClient-test.yml中 person.name改为wangwu并提交,再次访问http://localhost:8082/print,可以看到print打印的name依然是zhangsan,那么我们如何才能让git中文件发生变化后ConfigClient读取的配置也能实时跟着变化呢?我们知道ConfigServer会从远端拉取配置,然后在本地存一份,然后ConfigClient启动的时候会读取这个从ConfigServer传递的配置,但是当配置文件发生变化的时候,ConfigClient是无法感知的,因为ConfigServer并没有通知它,我们要解决这个问题就需要用到消息队列。spring cloud bus正好集成了这个功能,当远端配置文件发生变化是,它会对外提供一个/bus-refresh接口发送一个消息给ConfigClient
    1.ConfigServer
    添加maven依赖

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

    application.yml添加配置

    management:
      endpoints:
        web:
          expose: "*"
    

    相关文章

      网友评论

          本文标题:分布式配置中心的实现

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