微服务架构spring cloud - 分布式配置中心config(七)

1.什么是spring-cloud-config

用来为分布式系统中的基础设施和微服务应用提供集体化的外部配置支持,它分为服务端和客户端。服务端也就是config服务,客户端就是其他的微服务。

spring-cloud-config默认使用Git存储配置信息

2.配置服务端

首先配置依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

开启config服务端注解

@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

配置文件,主要是服务名和远程的git文件地址

spring.application.name=config-server
server.port=7001

spring.cloud.config.server.git.uri=https://gitee.com/eill/spring-cloud-config/
spring.cloud.config.server.git.search-paths=spring_cloud_in_action/config-repo
spring.cloud.config.server.git.username=13711919653
spring.cloud.config.server.git.password=llg1997729

配置好后按照服务地址加上远程文件的相对路径规则访问

第一种方法是直接按照application  profile   label  的顺序访问(由小到大的顺序),例如 在分支为llx下面的llg-test.properties文件则需要通过

http://localohsot:7001/llg/test/llx 访问,如果访问的是默认分支,则不需要加上label也就是llx

第二种方法是按照label  application.profile.properties 的顺序访问(由大到小的顺序),例如 在分支为llx下面的llg-test.properties文件则需要通过

http://localohsot:7001/llx/llg-test.properties 访问,如果访问的是默认分支,则不需要加上label也就是llx

  • /application/profile/label
  • /application-profile.yml
  • /label/applicaition-profile.yml
  • /application-profile.properties
  • /label/applicaition-profile.properties

配置文件本地备份

从日志文件可以看到,获取配置信息后会存储一份在config-server的文件系统中。所以即使远程文件访问不到也可以通过访问本地文件。

2018-08-10 10:23:54.018  INFO 4993 --- [nio-7001-exec-9] 
o.s.c.c.s.e.NativeEnvironmentRepository  : Adding property source: 
file:/var/folders/7_/p9dxm92s459dn2t78nkt57l40000gn/T/config-repo-
2575231988021900700/spring_cloud_in_action/config-repo/llg-prod.properties

3.配置客户端

首先配置依赖

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

在bootstrap.properties文件上配置信息,bootstrap.properties优先级比本地配置优先级高,否则会引入失败,信息被本地覆盖

  • applicaiont---------------->config - application
  • profile---------------->config - profile
  • label---------------->config - label
  • uri-------------------->config 服务地址
spring.application.name=llg
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:7001/

server.port=7002

随意写个Controller测试

@RefreshScope
@RestController
public class TestController {

    @Value("${from}")
    private String from;
    @Autowired
    private Environment environment;

    @RequestMapping("/from")
    public String from(){

        return this.from+environment.getProperty("from","undefined");
    }

}

4.服务端详解

客户端应用从配置管理中获取配置信息遵从下面的执行流程

  1. 应用启动时,根据bootstrap.properties中配置的应用名application、环境名profile、分支名label,向ConfigServer请求获取配置信息
  2. Config Server根据自己维护的Git仓库信息和客户端传递过来的配置定位信息去查看配置信息
  3. 通过git clone 命令将找到的配置信息下载到Config Server 的文件系统中
  4. Config Server创建Spring的ApplicationContext实例,并从Git本地仓库中加载配置文件,最后将这些配置内容读取出来返回给客户端应用
  5. 客户端应用在获得外部配置文件后加载到客户端的ApplicationContext实例,该配置内容的优先级高于Jar包内部配置的优先级,所以在Jar包中重复的内容将不再被加载。

Git配置仓库

远程git仓库

spring.cloud.config.server.git.uri=https://gitee.com/eill/spring-cloud-config/
spring.cloud.config.server.git.username=13711919653
spring.cloud.config.server.git.password=llg1997729

也可以通过本地仓库的方式运行

spring.cloud.config.server.git.uri=file://${user.home}/config-repo

占位符位置配置URI

通过占位符的方式可以一条表达式多个服务共用

spring.cloud.config.server.git.uri=https://gitee.com/eill/spring-cloud-config/{application}
spring.cloud.config.server.git.username=13711919653
spring.cloud.config.server.git.password=llg1997729

配置多个仓库

首先是配置默认的仓库,当使用{application}/{profile}的模式匹配的时候,如果找不到其他仓库则会用这个默认仓库

spring.cloud.config.server.git.uri=http://git.oschina.net/llg/config-repo

配置一个application为dev,profile任意的匹配模式

spring.cloud.config.server.git.repos.dev.pattern=dev/*
spring.cloud.config.server.git.repos.dev.uri=file://home/git/config-repo

配置一个applicaition为test的配置文件。profile为空

spring.cloud.config.server.git.repos.test=http://git.oschina.net/test/config-repo

配置一个application为dev,profile为pp开头的配置文件,并且可以配置多个匹配模式

spring.cloud.config.server.git.repos.prod.pattern=prop/pp*,online/oo*
spring.cloud.config.server.git.repos.prod.uri=http://git.oschina.net/prod/config-repo

总结:配置多个仓库的时候,Config Server在启动的时候会直接克隆底第一个仓库的配置内容,其他配置只会在请求的时候才会克隆到本地

子目录存储

从下面来看说明,uri配置的是仓库位置,不能写到子目录,所以特地用search-paths匹配到子目录,这样就可以一个仓库对应多个目录,一个目录对应一个服务了

spring.cloud.config.server.git.uri=https://gitee.com/eill/spring-cloud-config/
spring.cloud.config.server.git.search-paths=spring_cloud_in_action/config-repo

访问权限

当然了我们也可以用ssh,不过需要在git那边配置并且持有key

spring.cloud.config.server.git.username=13711919653
spring.cloud.config.server.git.password=llg1997729

SVN配置仓库

只需要将依赖改为svn依赖,并且将uri的开头http改成svn即可,其他无需改变

本地仓库

由于默认是随机存储,所以我们也可以指定目录存储

spring.cloud.config.server.git.basedir=/home/dev/
spring.cloud.confgi.server.svn.basedir=/home/dev/

本地文件系统

通过本地的文件系统加载配置文件,但是不推荐使用

默认从src/main/resource 目录搜索配置文件

spring.profiles.active=native

指定目录搜索文件

spring.cloud.config.server.native.search-locations=

健康监测

由于springcloud-config-server的配置自动创建了健康检测器,默认构建了一个application为app的仓库

而如果在配置文件是根据占位符{application}配置仓库的话就会有问题,application被替换成app,而实际仓库没有,则监测一直异常

解决方法一

Git仓库配置一个app-config的配置库,注意这个config是根据配置文件而来的,例如{application}-config

解决方法二

直接配置一个仓库,repositoties是Map对象,所以可以配置多个

spring.cloud.config.server.health.repositoties.check.name=check-repo

spring.cloud.config.server.health.repositoties.check.label=master

spring.cloud.config.server.health.repositoties.check.profiles=default
public void setRepositories(Map<String, ConfigServerHealthIndicator.Repository> repositories) {
        this.repositories = repositories;
    }

    public static class Repository {
        private String name;
        private String profiles = "default";
        private String label;

        public Repository() {
        }

        public String getName() {
            return this.name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getProfiles() {
            return this.profiles;
        }

        public void setProfiles(String profiles) {
            this.profiles = profiles;
        }

        public String getLabel() {
            return this.label;
        }

        public void setLabel(String label) {
            this.label = label;
        }
    }
spring.cloud.config.server.git.uri=https://gitee.com/eill/{application}
spring.cloud.config.server.git.search-paths=spring_cloud_in_action/config-repo
spring.cloud.config.server.git.username=13711919653
spring.cloud.config.server.git.password=llg1997729

spring.cloud.config.server.health.repositories.check.name=spring-cloud-config
spring.cloud.config.server.health.repositories.check.label=master
spring.cloud.config.server.health.repositories.check.profiles=default
spring.cloud.config.enabled=true

不使用检测器

spring.cloud.config.server.health.enabled=false

属性覆盖

可以将这些属性一并传给客户端,作为共同属性。不过客户端也可以更改优先级的配置方式来选择是否使用Config Server提供的默认值

spring.cloud.config.server.overrides.name=llg
spring.cloud.config.server.overrides.from=GD

安全保护

由于配置中心的一些敏感内容可以通过http访问,所以理所当然的我们需要权限控制,最方便的肯定就是使用spring security了

首先服务端配置账号密码

spring.security.user.name=llg
spring.security.user.password=1997729

客户端要想访问也必须配置响应的信息

spring.cloud.config.username=llg
spring.cloud.config.password=1997729

加密解密

由于防止敏感数据的明文方式泄密,所以需要加密

1.使用前提添加jce

下载后,加压文件,把local_policy.jar,US_export_policy.jar拷贝并覆盖到$JAVA_HOME/jre/lib/security

2.在config-server的bootstrap.properties中配置encrypt.key

encrypt.key=llg

3.通过config-server的断点进行加密和解密

  • /encrypt/status   查看加功能状态
  • /key  查看秘钥的端点
  • /encrypt 对请求的body内容进行加密
  • /decrypt 对请求的body内容进行解密
curl http://localhost:7001/encrypt -d llg

curl http://localhost:7001/decrypt -d c2a575fe92501564f02615a6f1b349fb9e54b0043fadc325d0d70d8737082a69

3.在git上的配置中心,对需要解密的乱码加上{cipher}

spring.datasource.username=llg
spring.datasource.password={cipher}c2a575fe92501564f02615a6f1b349fb9e54b0043fadc325d0d70d8737082a69

非对称加密

使用非对称加密安全性能更高

encrypt.key-store.location=liliguang.keystore
encrypt.key-store.alias=liliguang
encrypt.key-store.password=1997729
encrypt.key-store.secret=1997729
liliguangdeMacBook-Air:~ liliguang$ curl http://localhost:7001/encrypt -d llg
AQBQjCWCmYi0bRggHcgnzLKQlc1KAJnzT/4ObMD9gHPzw67oi+tWzXcWScIXF1LyItqfP68Tkxx+kIwBnTw
685b5VHM1UHHl0GmuVXcq4S3O5mZv4hZEszk3ViIDKy3rXuoPpTNn9tTfYvkeRKfjtExHFRysEaM45Fvi9i
Y5T3Oosz7t2G+gRwIsgpbj5zxLxaOSv7AhGQx0+ZG6zdYBkiLtZp0LCCnHO/wI7cFyJ8YOlam5/gt9NuCBT
SFoa+z7FUIbaC19hHxBNLZHuuilrrqjXVupaRf7fNV1ZfrRD7SHOASgYb3NqgWq8nQUxX5Ar4LdaSvQiiYZ
gdCkFjQAUPWUoliliguangdeMacBook-Air:~ liliguang$ 

通过环境变量配置更加安全,配置文件会自动加载

  • ENCRYPT_KEY_STORE_LOCATION
  • ENCRYPT_KEY_STORE_ALIAS
  • ENCRYPT_KEY_STORE_PASSWORD
  • ENCRYPT_KEY_STORE_SECRET

高可用配置

  • 传统方式:使用负载均衡器进行负载均衡,提供一个对外接口给其他服务
  • 服务模式:依然是使用eureka客户端,将自己注册到服务注册中心即可。非常棒!

5.客户端详解

URI指定配置中心

spring.application.name=llg
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:7001/
spring.cloud.config.username=llg
spring.cloud.config.password=1997729
server.port=7002

服务化配置中心

前提:config-server已经注册到注册中心Eureka Server上面

主体:将confgi-client注册到服务注册中心,并且配置文件上用服务名称代替真实url

  • enabled:开启用服务来访问配置中心
  • serveice-id:配置中心的服务名称
  • username:权限的账号
spring.application.name=llg

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server

spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.username=llg
spring.cloud.config.password=1997729
server.port=7002

失败快速响应与重试

有些较为大型的服务可能启动缓慢,但是我们想第一时间就知道是否能从配置中心取到配置信息。通过设置可以实现

spring.cloud.config.fail-fast=true

加入依赖即可开启重试机制

<dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
  • spring.cloud.config.retry.multiplier=1.1 下一间隔的乘数
  • spring.cloud.config.retry.initial-interval=1000  初始重试间隔时间 
  • spring.cloud.config.retry.max-interval=2000  最大间隔时间
  • spring.cloud.config.retry.max-attempts=6 最大重试机制

获取远程配置

1.通过向Config Server Get请求以直接的方式去获取

  • /application/profile/label
  • /application-profile.yml
  • /label/applicaition-profile.yml
  • /application-profile.properties
  • /label/applicaition-profile.properties

2.通过客户端配置方式加载

  • spring.application.name 对应配置文件中的{application}内容
  • spring.cloud.config.profile 对应配置文件中的{profile}内容
  • spring.cloud.config.label 对应分支内容,如不配置,默认为master

6.动态刷新配置

首先声明这是一个不完全的动态刷新,需要我们通过spring boot 提供的actuator来刷新

首先配置端点依赖,切记将权限控制关闭,否则需要权限。

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
management.security.enabled=false

当在Git上直接修改配置文件而config client 不重启的情况下,config client 通过post请求/refresh 端点即可刷新配置。这个行为还需要手动。所以后续使用 spring Cloud Bus 消息总线来实现配置变更。

猜你喜欢

转载自blog.csdn.net/m0_37834471/article/details/81557318