分布式配置中心的实现

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

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: "*"
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容