Spring cloud config配置中心初探


微服务系统,配置中心是其中重要的一环。
什么是配置中心?

配置中心的主要思想是将配置集中管理起来。它允许我们在一个地方管理不同环境和不同集群的配置信息。当配置发生变化时,配置中心能够实时地将更新推送到应用程序,从而实现动态更新,无需手动逐个修改每个实例的配置。

简而言之,配置中心就像是一个中央仓库,负责管理和分发配置信息。这样一来,我们就能够更高效地管理分布式系统的配置,降低维护成本,提高系统的可靠性和可维护性。

配置中心通常具备以下特点:

    1. 集中管理:所有的配置信息都存储在一个或多个集中的位置,便于统一管理和维护。
    1. 动态更新:应用程序可以实时接收配置的更新,而无需重启服务。
    1. 版本控制:配置信息的变更历史可以被记录和追踪,方便回滚到旧版本的配置。
    1. 权限管理:不同的用户或服务可能需要访问不同的配置信息,配置中心可以提供细粒度的权限控制。
    1. 环境隔离:可以为不同的环境(如开发、测试、生产)提供不同的配置信息。
    1. 服务发现:配置中心可以与服务发现机制集成,以便服务能够找到并使用正确的配置。
    1. 高可用性:配置中心自身需要具备高可用性,以确保应用程序始终能够访问到配置信息。
    1. 安全性:配置信息可能包含敏感数据,因此配置中心需要提供安全机制,如加密存储和传输。
    1. 监控和审计:配置中心可以提供监控配置使用情况和审计配置变更的功能。
    1. API支持:配置中心通常提供API,使得应用程序可以通过编程方式查询和更新配置。

常见的配置中心解决方案包括Spring Cloud Config、Consul、etcd、Apache ZooKeeper等。

本文将采用Spring Cloud Config方案,部署一个包含config实例。
请添加图片描述

0. 环境准备

  • JAVA 21
  • Spring Cloud 2023.0.1
  • Spring Boot 3.2.5
  • git

1. 搭建Eureka注册中心

Eureka Server本身也是一个Spring boot项目。

1.1 pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
    <relativePath/>
  </parent>

  <groupId>org.example.yy</groupId>
  <artifactId>eureka</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>eureka</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>


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

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>2023.0.1</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
    <repository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <releases>
        <enabled>false</enabled>
      </releases>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </pluginRepository>
    <pluginRepository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <releases>
        <enabled>false</enabled>
      </releases>
    </pluginRepository>
  </pluginRepositories>
</project>

1.2 启动类

package org.example.yy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;


@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {

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

这里需要添加注解EnableEurekaServer来启用 Eureka Server。

1.3 application.properties

spring.config.name=eureka-server
server.port=10000

eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false

eureka.server.renewalPercentThreshold=0.49

打开Eureka Server可以看到,服务已经启动好。
请添加图片描述

2. git repo

由于这里是本地环境测试,没有使用远端的git仓库,使用的是本地git repo,目录是:/Users/yuanyao/tmp/config-repo, 在指定目录下写了一个文件:

tech.book=kotlin-version

3. Config Server

Config Server是一个提供Config的中心。这个Config Server也是一个Eureka client,因此也需要注册到注册中心。

3.1 pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <groupId>org.example.yy</groupId>
  <artifactId>config-server</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>config-server</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
<!--    <dependency>-->
<!--      <groupId>org.springframework.boot</groupId>-->
<!--      <artifactId>spring-boot-starter-data-mongodb</artifactId>-->
<!--    </dependency>-->

  </dependencies>


  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>2023.0.1</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
    <repository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <releases>
        <enabled>false</enabled>
      </releases>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </pluginRepository>
    <pluginRepository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <releases>
        <enabled>false</enabled>
      </releases>
    </pluginRepository>
  </pluginRepositories>
</project>

这里主要添加Eureka client和Config Server的starter。

3.2 启动类

package org.example.yy;

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

@EnableConfigServer
@SpringBootApplication
@EnableDiscoveryClient
public class ConfigServer {

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

这里需要添加两个注解,分别EnableDiscoveryClient和EnableConfigServer.

3.3 application.properties

server.port=10001
spring.application.name=config-server
eureka.client.serviceUrl.defaultZone=http://localhost:10000/eureka/

spring.cloud.config.server.git.uri=file:///Users/yuanyao/tmp/config-repo
spring.cloud.config.label=master

这里不但需要配置使用的Eureka注册中心的地址,还要配置git repo的地址,同时还要配置,是使用的哪个分支。

3.4 注册到注册中心

这里启动这个Spring boot项目,可以看到,已经注册到注册中心。
请添加图片描述

3.5 配置的内容

我们可以通过rest接口查看配置的内容

curl http://localhost:10001/config-repo/master
{"name":"config-repo","profiles":["master"],"label":null,"version":"0c719f8639f9c2036f6f7f1293d90606e81365a1","state":null,"propertySources":[{"name":"file:///Users/yuanyao/tmp/config-repo/application.properties","source":{"tech.book":"kotlin-version5"}}]}%

注意,这里的config-repo是其中的git仓库名,master是分支名。
这里的配置内容是JSON格式

{
	"name": "config-repo",
	"profiles": ["master"],
	"label": null,
	"version": "0c719f8639f9c2036f6f7f1293d90606e81365a1",
	"state": null,
	"propertySources": [{
		"name": "file:///Users/yuanyao/tmp/config-repo/application.properties",
		"source": {
			"tech.book": "kotlin-version5"
		}
	}]
}

这里可以看到,我们已经读取到配置再配置中心的内容。

4.Config Client

4.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.example.yy</groupId>
    <artifactId>config-client</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
            <version>4.1.0</version>
        </dependency>

    </dependencies>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2023.0.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </pluginRepository>
    </pluginRepositories>

</project>

4.2 启动类

package org.example.configclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ConfigClient {

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

4.3 controller

package org.example.configclient.web;

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

@RestController
@RefreshScope
public class HelloController {

    @Value("${tech.book}")
    String bookName;

    @GetMapping("book")
    public ResponseEntity<String> book() {
        return ResponseEntity.ok(bookName);
    }
}

这里测试配置的内容tech.book的值,访问book接口,看返回即可。

4.4 bootstrap.properties

Config中有两个配置文件,一个是bootstrap.properties,另一个是application.properties。这两个文件的区别是:
bootstrap.properties主要用来配置一些系统级的配置,如配置中心的地址等。application.properties中主要存放应用级的配置内容。

eureka.client.serviceUrl.defaultZone=http://localhost:10000/eureka/

spring.cloud.config.discovery.service-id=CONFIG-SERVER
spring.cloud.config.discovery.enabled=true
spring.cloud.config.name=config-client
spring.cloud.config.label=master

3.4 application.properties

spring.application.name=config-client
server.port=10002

tech.book=java

4.5 启动

这个时候,再启动Config Client。这个时候,可以看到,该client也注册到注册中心了:
请添加图片描述

这个时候,我们访问接口,测试配置的值:
请添加图片描述
这里看到,已经是配置中心的值kotlin-version5了,而不是默认配置的java了。

5.动态更新值

配置中心还有一个重要功能,可以动态更新config的值,而不需要重新启动。这里有两种方案,一个是使用Spring boot actuator,这个是使用手动刷新来更新值。
另一种是使用spring config bus来进行自动更新。

5.1 actuator方式

只需要在config-client中引入starter:

<!--springcloud 使用/refresh端点手动刷新项目依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

然后再配置文件中配置,暴露所有接口:

management.endpoints.web.exposure.include=*

这个时候,我们更新git repo的值,将tech.book的值更新到version6,然后commit。
然后访问refresh接口,进行手动刷新:

 curl -X POST http://localhost:10002/actuator/refresh
["config.client.version","tech.book"]%

这个时候,已经刷新完成,此时再请求端口,可以看到值已经发生改变:
请添加图片描述

5.2 spring cloud bus

挖个坑,有人想看再填

6. 总结

本文只是记录了使用spring cloud config的一个示例,其中只涉及简单的实现,原理均无涉及。但是,学习了如何使用只是第一步,下一篇更新其实现原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值