一、简介

Spring Cloud Config 是 Spring Cloud 家族中较早的配置中⼼,Spring Cloud Config 是分布式系统中,为服务端和客⼾端解决配置管理的⽅案。它提供了集中化的配置管理,使得在不同环境(开发,测试,⽣产) 中管理应⽤程序配置变得更加简单和⼀致。它⽀持配置的动态刷新,允许在不重启应⽤的情况下更新配置,提⾼了系统的灵活性和响应速度。

核⼼组成
Spring Cloud Config 是⼀个分布式配置管理系统,它主要包括以下⼏个⽅⾯:

  1. Config Server(配置服务器)
    Config Server 是⼀个配置管理服务器,负责从各种后端存储(如Git、SVN、本地⽂件系统等)中拉取配置信息,并提供REST API供客⼾端使⽤
  2. Config Client(配置客⼾端)
    Config Client 是应⽤程序中⼀个组件,它允许应⽤程序通过Config Client连接到Config Server并动态获取配置信息。客⼾端可以根据环境,服务名等动态选择对应的配置⽂件
  3. 版本控制集成
    Spring Cloud Config 默认使⽤Git作为配置存储的后端,这样可以利⽤Git的版本控制功能来管理配置⽂件的版本。每个环境对应⼀个特定的版本,可以通过切换版本号来⾃动获取对应环境下的配置

二、搭建 config server

搭建Config Server的⽅式很简单,Spring Cloud Config Server是⼀个标准的Spring Boot应⽤程序,通过引⼊相应的依赖和注解即可快速启动。
主要分为以下⼏步:

  1. 创建项⽬
  2. 添加依赖
  3. 启⽤Config Server
  4. 完善配置
  5. 初始化Git仓库

2.1 创建项⽬

我们使用**【JavaEE】【SpringCloud】环境与工程搭建** , 这篇文章的项目接着实现。
创建空项目,

完善pom文件:

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>    
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

完善启动类

package com.cloud.config.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

2.2 添加依赖

添加spring-cloud-config-server依赖:

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

2.3 启⽤config server

在启动类添加注解@EnableConfigServer

2.4 完善配置

配置文件中

server:
  port: 7071
spring:
  application:
    name: config-server # 应⽤名称
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/yj20040627/config-server.git #配置⽂件Git 地址
          default-label: master #配置⽂件分⽀
          search-paths: config #配置⽂件所在根⽬录



2.5 初始化git仓库

创建git仓库
上传配置信息
config/config-server-dev.yml文件中:

data:
  env: config-dev
  user:
    username: config-dev
    password: config-dev

config/config-server-prod.yml文件中:

data:
  env: config-prod
  user:
    username: config-prod
    password: config-prod

2.6 测试

Spring Cloud Config 有它的⼀套访问规则,我们通过这套规则在浏览器上直接访问就可以。

  • /{application}/{profile}[/{label}]
  • /{application}-{profile}.yml
  • /{label}/{application}-{profile}.yml
  • /{application}-{profile}.properties
  • /{label}/{application}-{profile}.properties
  • {application}:表⽰微服务的名称,对应于配置中的 spring.application.name 属性。
  • {profile}:表⽰当前环境的配置⽂件,如dev,test,prod等,对应于 spring.profiles.active属性。
  • {label}:表⽰Git仓库中的分⽀,标签或提交ID。这个参数是可选的,如果省略,默认会使⽤ master 分⽀。{label} 对于回滚到以前的配置版本⾮常有⽤。

基于以上规则,我们可以访问以下地址,如果可以正常返回数据,则说明配置中⼼服务端⼀切正常。
http://127.0.0.1:7071/config-server/dev
http://127.0.0.1:7071/config-server/prod
http://127.0.0.1:7071/config-server-dev.yml
http://127.0.0.1:7071/config-server-prod.yml

三、config client

Config Client 简单来说,就是应⽤程序连接到Config Server并动态获取配置信息。客⼾端的配置相对简单只需要一下几步即可:

  1. 配置管理(配置中心配置信息)
  2. 添加config依赖
  3. 应用程序中配置 服务端信息(地址、环境)
  4. 测试:读取配置
  5. 多平台配置

3.1 配置管理

在git仓库添加配置
product-service-dev.yml

data:
  env: product-service-dev

product-service-prod.yml

data:
  env: product-service-prod

3.2 添加依赖

Spring Cloud 会创建⼀个 Bootstrap Context ,作为Spring 应⽤ “Application Context” 的⽗上下⽂。在Spring应⽤启动的初始化阶段, Bootstrap Context 负责从外部源(如Consul)加载配置属性并解析配置。

所以除了添加 spring-cloud-starter-config 依赖之外,还需要加⼊依赖 spring-cloudstarter-bootstrap来实现

在product-service的pom文件中添加依赖:

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

3.3 配置⽂件

Bootstrap属性具有⾼优先级,在 bootstrap.yml 或 bootstrap.properties 中定义的配置会优先于 application.yml或 application.properties 中的配置。

bootstrap.yml 主要⽤于配置应⽤启动时所需的外部依赖和环境,⽽ application.yml ⽤于业务逻辑相关的配置(如数据库连接等)
所以在product-service中添加一个文件:
bootstrap.yml

spring:
  profiles:
    active: dev
  application:
    name: product-service
  cloud:
    config:
      uri: http://127.0.0.1:7071 # 指定配置服务端的地址

3.4 读取配置

在product-service中写测试类:

package com.cloud.product.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/config")
@RestController
public class ConfigController {
    @Value("${data.env}")
    private String env;
    @RequestMapping("/getEnv")
    public String getEnv(){
        return "env:"+ env;
    }

}

3.5 多平台配置⽀持

如果我们的config server 是在不同的环境(url不同),我们就需要下面这种方式来读取配置。

bootstrap.yml

spring:
  profiles:
    active: prod
#配置两个版本的配置,并通过 spring.profiles.active 设置当前使⽤的版本
---
spring:
  config:
    activate:
      on-profile: prod
  application:
    name: product-service
  cloud:
    config:
      uri: http://localhost:7071
---
spring:
  config:
    activate:
      on-profile: dev
  application:
    name: product-service
  cloud:
    config:
      uri: http://localhost:7071

四、配置中⼼⾃动刷新

SpringCloud Config 在项⽬启动时加载配置内容这⼀机制,导致了它存在⼀个缺陷,修改配置⽂件内容后,不会⾃动刷新。

⽐如上⾯的项⽬,当服务启动之后,我们修改git上的配置,新的配置并不会被加载。

Spring Cloud Config提供了⼀个刷新机制,但是需要我们主动触发。

比如我们在git上修改一下配置,不重启服务,product-service的端口收到的还是原来没有修改的配置信息。

4.1 添加依赖

⾃动刷新机制,需要借助 Actuator 提供的功能,所以需要添加 spring-boot-starter-actuator 依赖

在product-service的pom文件中添加依赖:

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

spring-boot-starter-actuator 是 Spring Boot 提供的⼀个强⼤的监控和管理⼯具,它允许开发者查看和管理Spring Boot 应⽤的各种运⾏时指标和状态。核⼼功能有健康检查,收集和展⽰应⽤程序的运⾏指标,以及端⼝配置

/actuator/refresh 端点是 Spring Cloud Actuator 提供的⼀个功能,它允许在运⾏时动态刷新 Spring Cloud Config 客⼾端的配置。

4.2 添加 @RefreshScope

4.3 开启端点

在application.yml开启端点

management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

4.4 ⼿动刷新

启动服务,访问 http://127.0.0.1:9090/config/getEnv 修改配置后,发现配置并不能⽴即⽣效,需要⼿动调⽤⼀下接⼝ http://127.0.0.1:9090/actuator/refresh (POST请求)动态刷新 Spring Cloud Config 客⼾端的配置 (客⼾端服务接⼝)

4.5添加Weebhook

上述操作可以让我们的配置得到⽣效,但是每次修改都需要⼿动访问refresh接⼝,这样也很不⽅便。

Gitee 提供了⼀种 webhook 的⽅式,当有代码变更的时候,会调⽤我们设置的地址,来实现我们想达到的⽬的。添加WebHook- Gitee.com

选择配置的仓库,点击 管理 -> WebHooks -> 添加webHook

此处的URL需要为⼀个域名,在没有公⽹和域名的情况下,我们可以采⽤内⽹穿透的技术,暴露给外⽹。

实现内⽹穿透,常⻅的⽅法是使⽤第三⽅⼯具或服务,如ngrok,cpolar
cpolar操作:https://dashboard.cpolar.com/get-started
ngrok操作: https://ngrok.com/
具体操作可参考:2⾏代码将你的本地服务暴露在公⽹!-阿⾥云开发者社区

五、Spring Cloud Bus⾃动刷新

当我们启动了多个服务的时候,我们配置修改之后,每一个端口都要去手动刷新,非常麻烦。

Spring Cloud Bus 是Spring Cloud体系中的⼀个组件,主要⽤于在集群环境中传播分布式系统的配置变更,以及提供事件驱动的通信机制。 Spring Cloud Bus 核⼼原理其实就是利⽤消息队列做⼴播,所以要先有个消息队列,⽬前Spring Cloud Bus ⽀持两种消息代理:RabbitMQ和Kafka。
我们采⽤RabbitMQ实现。

在product-service中添加配置,修改为对应的IP,账号,密码和vhost

spring:
  rabbitmq:
    addresses: amqp://用户名:密码@IP:端口号/虚拟机

在product-service中引入bus的依赖

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

刷新配置:
启动服务,修改配置,刷新任⼀节点。
http://localhost:9090/actuator/busrefresh post⽅法
所有节点全部生效了

六、Spring Cloud Config 加密解密

在微服务开发中,配置⽂件可能包含⼀些敏感信息,⽐如数据库密码,API密码等,直接明⽂存储这些信息在配置⽂件中是⾮常危险的,尤其是当配置⽂件存储在版本控制系统(如Git)中时。这时候我们就需要对这些敏感信息进⾏加密。

针对这个问题,Spring Cloud Config提供了对属性进⾏加密解密的功能,以保护配置⽂件中的敏感数据不被泄露

6.1 密码算法分类

  1. 对称密码算法:是指加密秘钥和解密秘钥相同的密码算法。常⻅的对称密码算法有: AES、DES、3DES、RC4、RC5、RC6 等
  2. ⾮对称密码算法:是指加密秘钥和解密秘钥不同的密码算法。该算法使⽤⼀个秘钥进⾏加密,⽤另外⼀个秘钥进⾏解密。
    ◦ 加密秘钥可以公开,⼜称为 公钥
    ◦ 解密秘钥必须保密,⼜称为 私钥
    常⻅的⾮对称密码算法有: RSA、DSA、ECDSA、ECC 等
  3. 摘要算法:是指把任意⻓度的输⼊消息数据转化为固定⻓度的输出数据的⼀种密码算法。摘要算法是不可逆的,也就是⽆法解密。通常⽤来检验数据的完整性的重要技术,即对数据进⾏哈希计算然后⽐较摘要值,判断是否⼀致。常⻅的摘要算法有:MD5,SHA系列(SHA1,SHA2等),CRC(CRC8,CRC16,CRC32)

6.2 加密

6.2.1 环境

  1. 下载jar包(jdk9之前需要,之后不需要)
    Java 中提供了⼀套⽤于实现加密,密钥⽣成等功能的包 JCE(Java Cryptography Extension),这些包提供了对称,⾮对称等加密⽀持,但是默认的 JCE 是⼀个有限⻓度的 JCE,我们需要到 Oracle 官⽹去下载⼀个不限⻓度的 JCE

下载地址: https://www.oracle.com/java/technologies/javase-jce8-downloads.html


我们需要将 local_policy.jar 和 US_export_policy.jar 两个⽂件复制到 $JAVA_HOME/jre/lib/security ⽬录下,如果之前⽬录存在同名jar包,则覆盖即可。

  1. 添加配置
    在Config Server服务中添加bootstrap.yml⽂件,设置密钥
encrypt:
  key: gege666

  1. 添加bootstrap依赖
    config server v3.0.0以上时,bootstrap.yml⽂件不会加载,需要引⼊bootstrap相关的依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

6.2.2 对称加密解密

通过cmd,来观察加密解密

加密解密案例实现
通过Config Server 可以对数据进⾏加密,那么在Config Client中,就可以使⽤加密后的数据进⾏传输了。把加密后的数据,更新到git配置⽂件中,并在加密结果前添加 {cipher} ,如果远程属性源包含加密的内容(以 {cipher} 开头),则将其解密,通过Http发送给客⼾端。

data:
  env: product-service-prod
  password: '{cipher}6e93055b48779d30f89a6a6676394310a8cd8d2e29dce6143011de967fa11f38'

读取配置
product-service在ConfigController 添加代码

package com.cloud.product.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/config")
@RestController
@RefreshScope
public class ConfigController {
    @Value("${data.env}")
    private String env;
    
    @RequestMapping("/getEnv")
    public String getEnv(){
        return "env:"+ env;
    }
    @Value("${data.password}")
    private String password;
    @RequestMapping("/getPassword")
    public String getPassword(){
        return "password:"+ password;
    }



}

6.2.3 非对称加密解密

Spring Cloud Config 不仅可以使⽤对称性加密,也可以使⽤⾮对称性加密(⽐如 RSA 密钥对)。虽然
⾮对称性加密的密钥⽣成与配置相对复杂⼀些,但是它具有更⾼的安全性。

⾮对称加密要求我们先⽣成密钥对,密钥的⽣成我们可以使⽤ JDK 中⾃带的 keytool。

keytool 是⼀个 Java ⾃带的数字证书管理⼯具,keytool 将密钥(key)和证书 (certificates)存在⼀个称为 keystore 的⽂件中。它的位置在:%JAVA_HOME%\bin\keytool.exe ,可以直接使⽤cmd来调⽤打开cmd,输⼊命令:

keytool -genkeypair -keystore D:/config-server.keystore -alias config-server -keyalg RSA -keypass config -storepass config

-genkeypair 表⽰⽣成密钥对
-alias表⽰ keystore 关联的别名
-keyalg表⽰指定密钥⽣成的算法
-keystore指定密钥库的位置和名称
-keypass-storepass:密钥库⼝令和密钥⼝令

⽣成密钥之后,把密钥⽂件放在Config Server中

添加⾮对称加密的相关配置:

#encrypt:
#  key: gege666
encrypt:
  key-store:
    location: config-server.keystore #keystore⽂件存储路径 
    alias: config-server #密钥别名 
    password: config #storepass密钥仓库 
    secret: config #keypass ⽤来保护所⽣成密钥对中的密钥 

启动Config Server:
curl http://127.0.0.1:7071/encrypt -d root

加密解密案例实现
修改配置为⾮对称加密后的密⽂

data:
  env: product-service-prod
  password: '{cipher}AQCPIByYUIB2X51Q0aMGqNdVkxkjbYxpe5CVWBVjhaAAZcStQZqib3mWOhTJy8D3tmUXZLU7+ZOuKj01X3kQrJ2xKd7MSQtnxcsVwE4LJ92ll0WaTmgW4lczIkWy37TZ/3WJ4n6YDqJBNw04DKI9i6ipFVxBlqv/eiGccAY6W7KfjIWdFC3dFYltrwwYUyA9fysbkLqIxQ/tIsgzkj//A3r0sBlgJgJiLsEYoEGTQkOYl6q5xpwxfO1eKb6kjFBqHEGHNLiW6gFua1YAD8zi7Y+c96TrYYz4mK+Tp9UuAIH84ZapXIgk5NgAfLK4NYPyjOLsi0z9pF1DXjfQof9ThXvjf4vafrJyXazlRocE9JLG9cDtR7q6EIblRj01lZq8Ux8='

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐