Spring Cloud Config:分布式配置中心

好的,各位靓仔靓女们,欢迎来到今天的“Spring Cloud Config:分布式配置中心,让你的代码像变形金刚一样灵活!”专场。我是你们的老朋友,代码界的段子手,bug界的终结者,今天就让我们一起揭开 Spring Cloud Config 的神秘面纱,看看它如何拯救我们于配置地狱之中。

一、 前言:配置管理的那些痛点,你懂的!

在开始之前,我们先来聊聊配置管理这个话题。相信大家都有过这样的经历:

  • 改个配置,重启整个应用? 简直是噩梦!尤其是在线上环境,每次改个数据库密码、调整个缓存时间,都要提心吊胆地重启服务,生怕引起雪崩效应。
  • 配置散落在各个角落? application.properties、application.yml、环境变量…… 找起来像寻宝游戏,效率低下不说,还容易出错。
  • 不同环境配置不一致? 开发、测试、生产,三个环境的配置简直是三胞胎,长得像但又不一样。每次部署都要手动修改,一不小心就酿成大祸。
  • 配置信息敏感? 数据库密码、API Key,直接写在配置文件里,简直是把自己的内裤晒给隔壁老王看,毫无安全感可言。

这些痛点,相信大家都深有体会。想象一下,如果我们的代码也能像变形金刚一样,根据不同的环境,自动切换不同的配置,那该有多爽?Spring Cloud Config 就是来拯救我们的!

二、 Spring Cloud Config:配置界的瑞士军刀

Spring Cloud Config 是 Spring Cloud 全家桶中的一个重要组件,它是一个分布式配置中心,可以将配置信息集中管理,并提供统一的访问接口。简单来说,它就像一个配置界的瑞士军刀,功能强大,使用方便。

它的主要作用包括:

  • 集中管理配置: 将所有配置信息存储在一个地方,方便管理和维护。
  • 动态刷新配置: 可以在不重启应用的情况下,动态更新配置信息。
  • 版本控制: 可以对配置信息进行版本控制,方便回滚和审计。
  • 安全管理: 可以对配置信息进行加密,保护敏感信息。
  • 多环境支持: 可以根据不同的环境,加载不同的配置信息。

用一张图来概括 Spring Cloud Config 的架构:

graph LR
    Client --> ConfigServer;
    ConfigServer --> ConfigRepository;
    ConfigRepository --> GitRepository;
    subgraph Client
        A[Application]
    end
    subgraph ConfigServer
        B[Config Server]
    end
    subgraph ConfigRepository
        C[Configuration Files]
    end
    subgraph GitRepository
        D[Git Repository (e.g., GitHub, GitLab, Bitbucket)]
    end
    style A fill:#f9f,stroke:#333,stroke-width:2px
    style B fill:#ccf,stroke:#333,stroke-width:2px
    style C fill:#ccf,stroke:#333,stroke-width:2px
    style D fill:#ccf,stroke:#333,stroke-width:2px

简单解释一下:

  • Client (应用客户端): 你的应用程序,需要从配置中心获取配置信息。
  • Config Server (配置服务端): 负责管理配置信息,并提供访问接口。
  • Config Repository (配置仓库): 存储配置信息的地方,可以是 Git 仓库、SVN 仓库、数据库等等。
  • Git Repository (Git 仓库): 最常用的配置仓库,方便进行版本控制。

三、 快速上手:用 Spring Cloud Config 构建你的第一个配置中心

说了这么多,不如直接上手试试。下面我们来一步一步构建一个简单的 Spring Cloud Config 配置中心。

1. 创建 Config Server 项目

首先,我们需要创建一个 Spring Boot 项目,并添加 Spring Cloud Config Server 的依赖。

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

然后在 application.yml 中配置 Config Server:

server:
  port: 8888

spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your-username/your-config-repo  # 替换成你的 Git 仓库地址
          username: your-username                                  # 你的 Git 用户名
          password: your-password                                  # 你的 Git 密码 (不推荐直接写在这里,可以使用环境变量)
          default-label: main                                     # 默认分支,例如 main, master

注意:

  • spring.cloud.config.server.git.uri:指定 Git 仓库的地址。
  • spring.cloud.config.server.git.usernamespring.cloud.config.server.git.password:Git 仓库的用户名和密码。如果你的 Git 仓库是公开的,可以不用配置。强烈建议使用 SSH 协议,或者使用环境变量来配置密码,避免敏感信息泄露。
  • spring.cloud.config.server.git.default-label:指定 Git 仓库的默认分支。

最后,在启动类上添加 @EnableConfigServer 注解,开启 Config Server 功能。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

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

2. 创建 Config Client 项目

接下来,我们需要创建一个 Spring Boot 项目,作为 Config Client,从 Config Server 获取配置信息。

添加 Spring Cloud Config Client 的依赖:

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

然后在 bootstrap.yml (注意是 bootstrap.yml,不是 application.yml) 中配置 Config Client:

spring:
  application:
    name: my-application # 你的应用名称,需要和 Git 仓库中的文件名对应
  cloud:
    config:
      uri: http://localhost:8888 # Config Server 的地址
      profile: dev              # 环境名称,例如 dev, test, prod

注意:

  • spring.application.name:你的应用名称,这个名称需要和 Git 仓库中的文件名对应。例如,如果你的应用名称是 my-application,那么 Git 仓库中应该有 my-application.propertiesmy-application.yml 文件。
  • spring.cloud.config.uri:Config Server 的地址。
  • spring.cloud.config.profile:环境名称,例如 devtestprod。Config Server 会根据这个环境名称,加载不同的配置文件。例如,如果环境名称是 dev,那么 Config Server 会尝试加载 my-application-dev.propertiesmy-application-dev.yml 文件。

3. 创建 Git 仓库,并添加配置文件

现在,我们需要创建一个 Git 仓库,并在其中添加配置文件。配置文件的命名规则如下:

{application}-{profile}.{format}

  • application:应用名称,对应 spring.application.name
  • profile:环境名称,对应 spring.cloud.config.profile
  • format:文件格式,可以是 propertiesyml

例如,如果我们的应用名称是 my-application,环境名称是 dev,那么配置文件可以是 my-application-dev.propertiesmy-application-dev.yml

举个例子:

在 Git 仓库中创建一个 my-application-dev.properties 文件,内容如下:

my.message=Hello, Dev!

4. 在 Config Client 中获取配置信息

在 Config Client 中,我们可以使用 @Value 注解来获取配置信息。

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

@RestController
public class MyController {

    @Value("${my.message}")
    private String message;

    @GetMapping("/message")
    public String getMessage() {
        return message;
    }
}

5. 启动 Config Server 和 Config Client

现在,我们可以分别启动 Config Server 和 Config Client。

访问 Config Client 的 /message 接口,你应该可以看到 "Hello, Dev!" 的信息。

恭喜你,你已经成功构建了一个简单的 Spring Cloud Config 配置中心!🎉🎉🎉

四、 进阶技巧:让你的配置中心更上一层楼

上面的例子只是一个简单的入门,Spring Cloud Config 还有很多高级特性,可以帮助我们更好地管理配置信息。

1. 动态刷新配置

Spring Cloud Config 支持动态刷新配置,可以在不重启应用的情况下,更新配置信息。这对于线上环境的配置修改非常有用。

要实现动态刷新配置,需要以下几个步骤:

  • 在 Config Client 的 pom.xml 中添加 spring-boot-starter-actuator 依赖。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • application.yml 中开启 management 暴露 refresh 端点。
management:
  endpoints:
    web:
      exposure:
        include: refresh
  • 在需要动态刷新的 Bean 上添加 @RefreshScope 注解。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope // 添加 @RefreshScope 注解
public class MyController {

    @Value("${my.message}")
    private String message;

    @GetMapping("/message")
    public String getMessage() {
        return message;
    }
}
  • 修改 Git 仓库中的配置文件,并提交。
  • 调用 Config Client 的 refresh 端点,刷新配置信息。
curl -X POST http://localhost:8080/actuator/refresh

2. 配置加密

Spring Cloud Config 支持对配置信息进行加密,保护敏感信息。

要实现配置加密,需要以下几个步骤:

  • 在 Config Server 的 pom.xml 中添加 spring-cloud-config-server 依赖。 (之前已经添加过了)

  • 生成密钥。

java -jar spring-cloud-config-server.jar --encrypt.key=your-secret-key

注意: your-secret-key 是你的密钥,请妥善保管。

  • 使用密钥加密配置信息。
curl -X POST -d 'my.password=your-password' http://localhost:8888/encrypt
  • 将加密后的配置信息添加到 Git 仓库中,并在前面加上 {cipher} 前缀。

my.password={cipher}AQAPcm5nK+9B04xT2P4hY4hU9m2rIuJ/3X+o+X/Jj9n2w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6v9w2u05xY4hZ9w4yZ7o6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注