分布式配置中心

基本用法

分布式配置中心解决方案:
国内:

  • 360:Qconf
  • 淘宝: diamond
  • 百度:disconf
    国外:
  • Apache Commons Configuration
  • owner
  • cfg4j

简介

Spring Cloud Config 是一个发布式系统配置管理的解决方案,它包含了Client和Server。配置文件放在Server端,通过接口的形式提供给Client
Spring Cloud Config主要功能:
集中管理各个环境、各个微服务的配置文件
提供服务端和客户端支持
配置文件修改后,可以快速生效
配置文件通过 Git/SVn 进行管理,天然支持版本回退功能。
支持高并发查询、也支持多种开发语言。

准备工作

准备工作主要是给GitHub上提交数据
本地配置好相应的配置文件,提交到GitHub

ConfigServer

首先创建一个ConfigServer工程,创建时添加ConfigServer依赖:

项目创建成功后,项目启动类上添加注解,开启config server功能:

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

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

}

然后在配置文件中配置仓库的基本信息:

spring.application.name=config-server
server.port=8082
# 配置文件仓库地址
spring.cloud.config.server.git.uri=https://github.com/snowqwl/configRepo.git
# 仓库中,配置文件的目录
spring.cloud.config.server.git.search-paths=client1
# 仓库的用户名密码
spring.cloud.config.server.git.username=2214093189@qq.com
spring.cloud.config.server.git.password=

启动项目后,就可以访问配置文件了。访问地址:http://localhost:8082/client1/prod/master

实际上,访问地址有如下规则:
/{application}/{profile}/[{label}]
/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.yml
/{label}/{application}-{profile}.properties

application表示文件名
profile表示配置文件profile,例如test,dev,prod
label表示git分支,参数可选,默认就是master
接下来,可以修改配置文件,并且重新提交到 GitHub,此时,刷新 ConfigServer 接口,就可以及时看
到最新的配置内容

ConfigClient

创建一个SpringBoot 项目,添加ConfigClient依赖

项目创建成功后,resources目录下,添加bootstrap.properties配置,内容如下:

# 下面三行配置,分别对应config-server 中的{application},{profile}以及{label}占位符
spring.application.name=client1
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:8082
server.port=8083

接下来创建一个HelloController进行测试

@RestController
public class HelloController {
    @Value("${javaboy}")
    String javaboy;

    @GetMapping("/hello")
    public String hello(){
        return javaboy;
    }
}

配置

使用占位符灵活控制查询目录
修改config-server配置文件

spring.cloud.config.server.git.search-paths={application}

这里的{application}占位符,表示链接上来的client1的spring.application.name属性的值。
在config-server中,也可以用{profile}表示client的spring.cloud.config.profile,也可以用{label}表示client的spring.cloud.config.label
虽然在实际开发中,配置文件一般放在Git仓库中,但是,config-server也支持将配置文件放在classpath下。
在config-server中添加如下配置:

# 表示让 config-server 从 classpath 下查找配置,而不是去 Git 仓库中查找
spring.profiles.active=native

也可以在 config-server 中,添加如下配置,表示指定配置文件的位置:

spring.cloud.config.server.native.search-locations=file:/E:/properties/

配置文件加解密

常见加密方案

  • 不可逆加密
  • 可逆加密
    不可逆加密,就是理论上无法根据加密后的密文推算出明文,一般用在密码的加密上,常见的算法如MD5消息摘要算法,SHA安全散列算法。
    可逆加密,看名字就知道可以根据加密后的密文推断出明文的加密方式,可逆加密一般又分为两种:
  • 对称加密
  • 非对称加密
    对称加密指加密的密钥和解密的密钥是一样的,常见算法des,3des,aes
    非对称加密就是加密的密钥和解密的密钥不一样,加密的叫做公钥,可以告诉任何人,解密的叫做私钥,只有自己知道,常见算法:RSA

对称加密

首先下载不限长度的 JCE:http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip 将下载的文件解压,解压出来的 jar 拷贝到 Java 安装目录中:C:\Program Files\Java\jdk-13.0.1\lib\security
然后,在 config-server 的 bootstrap.properties 配置文件中,添加如下内容配置密钥:

# 密钥
encrypt.key=javaboy

然后,启动 config-server ,访问如下地址,查看密钥配置是否OK:http://localhost:8082/encrypt/status

然后,访问:http://localhost:8082/encrypt ,注意这是一个 POST 请求,访问该地址,可以对一段明文进行加密。把加密后的明文存储到 Git 仓库中,存储时,要注意加一个 {cipher} 前缀。


提交到github上

非对称加密

非对称加密需要我们首先生成一个密匙对。
在命令行执行如下命令,生成keystore

keytool -genkeypair -alias config-server -keyalg RSA -keystore
D:\springcloud\config-server.keystore

命令执行完成后,拷贝生成的keystore文件到config-server的resources目录下。
然后在config-server的bootstrap.properties目录中,添加如下配置:

encrypt.key-store.location=config-server.keystore
encrypt.key-store.alias=config-server
encrypt.key-store.password=111111
encrypt.key-store.secret=111111

重启 config-server ,测试方法与对称加密一致。
注意,在 pom.xml 的 build 节点中,添加如下配置,防止 keystore 文件被过滤掉。

 <resources>
    <resource>
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.keystore</include>
        </includes>
    </resource>
</resources>


安全管理

防止用户直接访问config-server看到配置文件内容,我们可以用spring security来保护config
首先在config-server中添加spring security依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.3.2.RELEASE</version>
</dependency>

添加完依赖后,config-server接口就自动被保护起来了。
默认自动生成的密码不好记,所以我们可以在config-server中,自己配置用户名和密码。
在config-server的配置文件中,添加如下配置,固定用户名密码:

spring.security.user.name=javaboy
spring.security.user.password=123

然后在config-client的bootstrap.properties配置文件中,添加如下配置:

spring.cloud.config.username=javaboy
spring.cloud.config.password=123

服务化

前面的配置都是直接在config-client中写死config-server的地址
首先启动Eureka.然后,为了让config-server和config-client能注册到Eurake,给它两添加如下依赖:

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

然后,在application.properties配置文件中配置注册信息。

eureka.client.service-url.defaultZone=http://localhost:1111/eureka

然后,修改config-client的配置文件,不再直接写死config-server的地址了。

# 下面三行配置,分别对应 config-server 中的 {application}、{profile}以及{label}占位符
spring.application.name=client1
spring.cloud.config.profile=dev
spring.cloud.config.label=master
#spring.cloud.config.uri=http://localhost:8081
# 开启通过 eureka 获取 config-server 的功能
spring.cloud.config.discovery.enabled=true
# 配置 config-server 服务名称
spring.cloud.config.discovery.service-id=config-server
server.port=8082
spring.cloud.config.username=javaboy
spring.cloud.config.password=123
eureka.client.service-url.defaultZone=http://localhost:1111/eureka

注意,加入 eureka client 之后,启动 config-server 可能会报错,此时,我们重新生成一个 jks 格式的
密钥。

keytool -genkeypair -alias mytestkey -keyalg RSA -keypass 111111 -keystore
D:\springcloud\config-service.jks -storepass 111111

生成之后,拷贝到 configserver 的 resources 目录下,同时修改 bootstrap.properties 配置。

# 密钥
#encrypt.key=javaboy
encrypt.key-store.location=classpath:config-service.jks
encrypt.key-store.alias=mytestkey
encrypt.key-store.password=111111
encrypt.key-store.secret=111111
spring.security.user.name=javaboy
spring.security.user.password=123

同时也修改一个pom.xml中的过滤条件

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.jks</include>
        </includes>
    </resource>
</resources>


动态刷新

当配置文件发生变化之后,config-server 可以及时感知到变化,但是 config-client 不会及时感知到变化,默认情况下,config-client 只有重启才能加载到最新的配置文件。
首先给 config-client 添加如下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.3.3.RELEASE</version>
</dependency>

然后,添加配置,使 refresh 端点暴露出来:

management.endpoints.web.exposure.include=refresh

最后,再给 config-client 使用了配置文件的地方加上 @RefreshScope 注解,这样,当配置改变后,只需要调用 refresh 端点,config-client 中的配置就可以自动刷新。

@RestController
@RefreshScope
public class HelloController {
    @Value("${javaboy}")
    String javaboy;

    @GetMapping("/hello")
    public String hello(){
        return javaboy;
    }
}

重启 config-client,以后,只要配置文件发生变化,发送 POST 请求,调用 http://localhost:8082/actu
ator/refresh 接口即可,配置文件就会自动刷新。

请求失败重试

config-client 在调用 config-server 时,一样也可能发生请求失败的问题,这个时候,我们可以配置一个请求重试的功能。
要给 config-client 添加重试功能,只需要添加如下依赖即可:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.3.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.5.RELEASE</version>
</dependency>

然后,修改配置文件,开启失败快速响应。

# 开启失败快速响应
spring.cloud.config.fail-fast=true

然后,注释掉配置文件的用户名密码,重启 config-client,此时加载配置文件失败,就会自动重试。

也可以通过如下配置保证服务的可用性:

# 开启失败快速响应
spring.cloud.config.fail-fast=true
# 请求重试的初识间隔时间
spring.cloud.config.retry.initial-interval=1000
# 最大重试次数
spring.cloud.config.retry.max-attempts=6
# 重试时间间隔乘数
spring.cloud.config.retry.multiplier=1.1
# 最大间隔时间
spring.cloud.config.retry.max-interval=2000
posted @ 2020-08-16 00:03  柒丶月  阅读(271)  评论(0编辑  收藏  举报