Spring Cloud(四)配置中心Config

本文详细介绍如何使用Spring Cloud Config构建基于Git和MySQL的分布式配置中心,实现配置文件的统一管理和实时更新,涵盖Server端搭建、客户端改造及配置刷新机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库以及数据库中。在spring cloud config 组件中,分两个角色,一是config server,二是config client。

在本文中,我们将分别构建基于Git、基于Mysql 数据库存储的分布式配置中心,并对客户端进行改造,并让其能够从配置中心获取配置信息并绑定到代码中的整个过程。

基于GIT存储

理解配置中心搜索路径

配置信息的URL与配置文件的映射关系如下:

- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.properties

准备配置仓库

在这里,我在 Gitee 上创建了一个公开的 repo, config-repo-demo 里面创建 mz-eureka-client-one 的文件夹,存放 mz-eureka-client-one 项目的配置文件。地址:https://gitee.com/mrzhouy/config-repo-demo

构建 Server 端

创建一个 SpringBoot 的基础项目 mz-config-server-git ,同时引入 config 的依赖 spring-cloud-config-server

POM 文件如下:

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

创建项目配置文件 bootstarp.yml , 配置如下:

eureka:
    client:
        serviceUrl:
            defaultZone: http://localhost:1001/eureka/
server:
    port: 1003
spring:
    application:
        name: mz-config-server-git
    cloud:
        config:
            server:
                git:
                    searchPaths: '{application}'
                    uri: https://gitee.com/mrzhouy/config-repo-demo

spring clour config git 属性解释:

uri: 仓库地址
username:访问账号(私库才需要输入)
password:账号密码(私库才需要输入)
searchPaths:git仓库子目录

当然,在某些时候我们希望对不同的子项目访问不同的git仓目录,因此我们可以在使用如下配置:

searchPaths: '{application}'

注:config 客户端在没有 spring.cloud.config.name属性的时候,服务端{application} 获取的是客户端 
spring.application.name的值,否则,获取的是 spring.cloud.config.name的值。 
1)、当没有spring.cloud.config.name时,客户端获取的是spring.application.name 所对应的git库中的文件,并且只能获取一个文件, 
2)、当一个项目中有需求要获取多个文件时,就需要用到spring.cloud.config.name这个属性,以逗号分割
开启服务

启动类上添加 @EnableConfigServer 注解开启 config server 服务。代码如下:

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(ConfigServerApplication.class);
    }
}

升级客户端(client)

客户端这里,我们直接在之前的 mz-eureka-client-one 项目中进行升级。

添加config依赖:

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

修改配置文件 bootstarp.yml 添加 config 配置:

spring:
    cloud:
        config:
            discovery:
                enabled: true
                service-id: mz-config-server-git
                #uri: http://localhost:8888/
            label: master
            profile: test
    
#注:如果config server 没有注入到注册中心,我们在这里可以通过 uri 来指定配置中心地址。但是生产、测试、开发环境中,我的配置中心是多个,因此我是将配置中心注册到了注册中心,通过 service-id 来访问注册中心的。

改造 HelloController:

@RestController
public class HelloController {
    @Value("${server.port}")
    private String serverPort;
    @Value("${info.message}")
    private String infoMessage;
    @RequestMapping("hi")
    public String sayHi() {
        return "Hi Spring Cloud, running in port :" + serverPort + "     info.message is : " + infoMessage;
    }
}

至此,配置中心已经构建完成,按顺序启动 注册中心、配置中心 、客户端。 调用 http://localhost:2001/hi ,我们可以看到通过配置中心拿到的 info.message 这个值。

基于 MySql 存储

前面我们已经完成了基于 GIT 存储的配置中心,其实升级为mysql存储很简单。只需要修改 POM 依赖(引入数据库依赖),以及 bootstarp.yml 属性文件即可。在这里,我们创建新的项目 mz-config-server-mysql ,POM 文件如下:

<parent>
        <artifactId>SpringCloud-Learning</artifactId>
        <groupId>com.mz</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mz-config-server-mysql</artifactId>
    <description>Spring Cloud 配置中心——MySql</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</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-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>
    </dependencies>

修改 bootstarp.yml

指定 spring.profiles.active = jdbc,然后增加 jdbc配置

eureka:
    client:
        serviceUrl:
            defaultZone: http://localhost:1001/eureka/
server:
    port: 1003
spring:
    application:
        name: mz-config-server-mysql
    profiles:
        active: jdbc
    cloud:
        config:
            label: master
            server:
                jdbc:
                    sql: SELECT `KEY`, `VALUE` from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?
    datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/db_microserver_config
        username: root
        password: TW123

创建数据库的sql 文件在项目中:ConfigMySql.sql

至此,修改完成,按顺序启动 注册中心、配置中心 、客户端(记得修改配置中心的serverId哦)。 调用 http://localhost:2001/hi ,我们可以看到通过配置中心拿到的 info.message 这个值。

Refresh

上面我们成功的完成了配置中心,但是这个时候就产生了疑问,client是在项目启动的时候就请求了配置中心,获取到了配置,如图:
在这里插入图片描述

那再我们修改完配置中心的配置后,如何刷新配置呢。如果需要重启项目的话,配置中心就会显得比较鸡肋。

别急,spring cloud 当然为我们提供了刷新的办法。仅修改客户端即 mz-eureka-client-one 项目,就可以实现 refresh 的功能。

添加依赖

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

增加了spring-boot-starter-actuator包,spring-boot-starter-actuator是一套监控的功能,可以监控程序在运行时状态,其中就包括/actuator/refresh的功能。

开启更新机制

需要给加载变量的类上面加载@RefreshScope,在客户端执行/actuator/refresh的时候就会更新此类下面的变量值。

@RestController
@RefreshScope
public class HelloController {
    @Value("${server.port}")
    private String serverPort;
    @Value("${info.message}")
    private String infoMessage;
    @RequestMapping("hi")
    public String sayHi() {
        return "Hi Spring Cloud, running in port :" + serverPort + "     info.message is : " + infoMessage;
    }
}

配置

Spring Boot 1.5.X 以上默认开通了安全认证,所以要在配置文件 application.yml 中添加以下配置以将/actuator/refresh这个 Endpoint 暴露出来

management:
  endpoints:
    web:
      exposure:
        include: refresh

测试

改造完之后,我们重启 mz-eureka-consumer-one,我们以 POST 请求的方式来访问 http://localhost:2001/actuator/refresh 就会更新配置文件至最新版本。

测试流程:

  1. 访问 http://localhost:2001/hi 返回Hi Spring Cloud, running in port :2001 info.message is : i am config by jdbc
  2. 我将 Git 上对应配置文件里的值改为i am config by jdbc update
  3. 发送 Post 请求到 http://localhost:2001/actuator/refresh
  4. 访问 http://localhost:2001/hi 返回Hi Spring Cloud, running in port :2001 info.message is : i am config by jdbc update

不过,每次手动刷新客户端也很麻烦,有没有什么办法只要提交代码就自动调用客户端来更新呢,Github 的 Webhook 是一个办法。

Webhook

Webhook 是当某个事件发生时,通过发送 HTTP POST 请求的方式来通知信息接收方。Webhook 来监测你在 Github.com 上的各种事件,最常见的莫过于 push 事件。如果你设置了一个监测 push 事件的 Webhook,那么每当你的这个项目有了任何提交,这个 Webhook 都会被触发,这时 Github 就会发送一个 HTTP POST 请求到你配置好的地址。

如此一来,你就可以通过这种方式去自动完成一些重复性工作,比如,你可以用 Webhook 来自动触发一些持续集成(CI)工具的运作,比如 Travis CI;又或者是通过 Webhook 去部署你的线上服务器。下图就是 Github 上面的 Webhook 配置。
在这里插入图片描述

  • Payload URL :触发后回调的 URL
  • Content type :数据格式,两种一般使用 json
  • Secret :用作给 POST 的 body 加密的字符串。采用 HMAC 算法
  • events :触发的事件列表。
events 事件类型描述
push仓库有 push 时触发。默认事件
create当有分支或标签被创建时触发
delete当有分支或标签被删除时触发

这样我们就可以利用 hook 的机制去触发客户端的更新,但是当客户端越来越多的时候,hook 机制也不够优雅了,另外每次增加客户端都需要改动 hook 也是不现实的。其实,Spring Cloud 给了我们更好解决方案——Spring Cloud Bus。后续我们将继续学习如何通过 Spring Cloud Bus 来实现以消息总线的方式进行通知配置信息的变化,完成集群上的自动化更新。

项目地址

码云
GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值