Spring Cloud Config 实现配置中心及自动刷新

why

微服务数量多,修改配置需要重启服务或无法集中统一修改,所以有了spring cloud config,同类型的还有360的QConf、淘宝的diamond、百度的discon都是解决配置集中管理的问题

what

spring cloud config 可以为微服务架构中的应用提供集中化的外部配置支持,它分为服务端、客户端两部分

如何实现配置中心?

这里我们选择将配置保存在github中,让spring cloud config去读取github仓库中的配置。
《Spring Cloud Config 实现配置中心及自动刷新》

核心功能

  • 集中管理各个环境的配置文件
  • 支持版本管理,github天然的支持
  • 支持大并发查询

环境

  • spring cloud version:Greenwich.SR2
  • spring boot version:2.1.7.RELEASE
  • jdk version:1.8

实现过程

接下来我们通过一个简单的示例来介绍如何实现一个简单的spring cloud config

配置github仓库

https://github.com/yousiqi/springcloud-config
可以直接fork或使用如上地址进行测试
《Spring Cloud Config 实现配置中心及自动刷新》

创建eureka-server模块

这个就不做赘述,都是spring cloud那一套

创建config-server模块

此模块主要是向git仓库中获取配置,并对外提供配置中心服务

在pom.xml文件中添加依赖:

        <!--配置服务-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

        <!--当作一个结点注册到注册中心-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

在application.yml中配置:

server:
  port: 8901
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git: #配置存储配置信息的Git仓库
          uri: https://github.com/yousiqi/springcloud-config.git
          clone-on-start: true #开启启动时直接从git获取配置
          search-paths: '{application}'
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8001/eureka/

在启动类中增加自动配置注解:

@EnableConfigServer // 开启配置服务
@EnableDiscoveryClient // 开启服务发现
@SpringBootApplication
public class ConfigServerApplication { 

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

配置好配置中心仓库、eureka-server、config-server后,可以启动项目,通过config-server获取配置信息,基本规则如下:

# 获取配置信息
/{ label}/{ application}{ profile}
# 获取配置文件信息
/{ label}/{ application}{ profile}.yml
  • application:代表应用名称,默认为配置文件中的spring.application.name,如果配置了spring.cloud.config.name,则为该名称
  • label:代表仓库分支的名称,对应配置文件中的spring.cloud.config.label,默认值是在服务器上设置的(对于基于git的服务器,通常是“master”)
  • profile:代表环境名称,对应配置文件中的spring.cloud.config.profile

测试:
配置环境配置信息:http://localhost:8901/master/config-dev
《Spring Cloud Config 实现配置中心及自动刷新》
获取配置文件内容:http://localhost:8901/master/config-dev.yml
《Spring Cloud Config 实现配置中心及自动刷新》
可以通过修改不同的url地址来访问不同环境不同文件的配置信息

创建config-client模块

真正使用配置的模块,通过对config-server的访问来动态获取配置信息

在pom.xml中添加依赖:

        <!--配置模块-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!--注册到服务中心-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

bootstrap.yml中配置(注意命名):

# 【注意】这个文件的名字是bootstrap,因为要在启动的时候配置
#
server:
  port: 9001
spring:
  application:
    name: config-client
  cloud:
    config: #Config客户端配置
      profile: dev #启用配置后缀名称
      label: dev #分支名称
      uri: http://localhost:8901 #配置中心地址
      name: config #配置文件名称
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8001/eureka/

在启动类中配置:

@EnableDiscoveryClient // 开启服务发现
@SpringBootApplication
public class ConfigClientApplication { 

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

然后再创建一个controller来对外提供接口,来测试看看配置是否成功获取:

/** * 获取配置api * * @author 游四七 * @date 2021/1/30 */
@RestController
public class ConfigClientController { 

    /** * 注入配置中心获取的配置 */
    @Value("${config.info}")
    private String configInfo;

    /** * http://localhost:9001/configInfo */
    @GetMapping("/configInfo")
    public String getConfigInfo() { 
        return configInfo;
    }
}

然后调用接口获取配置信息:http://localhost:9001/configInfo,可以获取到dev分支下的dev环境配置:

config info for dev(dev)

至此,你已经完成了一个基本的配置中心环境搭建了,但是有如下几个问题:

  1. 配置多的时候需要分多个目录进行管理
  2. 配置修改后需要重启应用才能生效
  3. 配置中心当前是公开的,需要增加账户认证来保证安全性
  4. 配置修改后无法自动通知所有应用刷新配置
  5. 单台config-server宕机问题

获取子目录配置

当我们很多的微服务都指向同样的配置中心,如果文件都是在同一层级,不好管理,所以最好的能够分文件夹进行管理,这时就需要让config-server能够搜索到子目录的配置信息

  1. 在config-server添加搜索路径占位符search‐paths: '{application}',表示对于不同的应用,访问的目录也不同
spring:
  cloud:
    config:
      server:
        git:
          search-paths: '{ application}' # 搜索路径占位符,否则为git仓库根路径
  1. 重启config-server、config-client,然后重新访问http://localhost:9001/configInfo,发现读取的是config目录下的配置信息
config info for config dir dev(dev)

支持手动刷新配置

当我们git仓库中的配置信息修改后,可以通过SpringBoot Actuator的refresh端点来刷新客户端配置信息,在config-client模块中修改如下信息:

  1. pom.xml添加actuator依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
  2. 在bootstrap.yml中暴露refresh端点

    management:
      endpoints:
        web:
          exposure:
            include: 'refresh'
    
  3. 在ConfigClientController类上增加@RefreshScope注解用于刷新配置

  4. 重新启动config-client模块,修改对应配置文件信息后,调用refresh端点(POST请求)进行手动刷新配置http://localhost:9001/actuator/refresh

  5. 再次访问http://localhost:9001/configInfo进行测试,可以发现配置已经更新为最新修改的内容了

添加配置中心安全认证

通过整合SpringSecurity来为配置中心添加安全认证

再创建一个config-security-server模块进行测试

  • pom.xml添加依赖

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-config-server</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
  • 在application.yml中配置:

    server:
      port: 8905
    spring:
      application:
        name: config-security-server
      cloud:
        config:
          server:
            git:
              uri: https://github.com/yousiqi/springcloud-config.git
              clone-on-start: true #开启启动时直接从git获取配置
      security: #配置用户名和密码
        user:
          name: siqi
          password: 123456
    
  • 启动config-security-server,访问:http://localhost:8905/master/config-dev.yml就无法访问了,需要进行login,只有登陆后才能正常访问
    《Spring Cloud Config 实现配置中心及自动刷新》

  • 在config-client中也要修改配置才能正常安全访问配置中心:

server:
  port: 9002
spring:
  application:
    name: config-client
  cloud:
    config:
      profile: dev #启用配置后缀名称
      label: dev #分支名称
      uri: http://localhost:8905 #配置中心地址
      name: config #配置文件名称
      username: siqi
      password: 123456

访问http://localhost:9002/configInfo进行测试,发现可以获取到配置信
息。
config info for dev(dev)

配置自动刷新

是通过Spring Cloud Bus+WebHook实现配置自动刷新的,详情参见:https://blog.csdn.net/qq_32828253/article/details/113574502

config-server集群搭建

在微服务架构中,所有服务都是从配置中心获取配置,配置中心一旦宕机,会发生很严重的生产事故,所以必须要有≥2的config-server

  1. 启动两个config-server分别运行在8902、8903上

  2. 添加config-client配置文件boostrap-cluster.yml,主要是添加从注册中心获取配置的地址配置,去除了显示指定某个ip+port的方式

    server:
      port: 9003
    spring:
      application:
        name: config-client
      cloud:
        config:
          profile: dev #启用环境名称
          label: dev #分支名称
          name: config #配置文件名称
          discovery:
            enabled: true
            service-id: config-server # 注册中心名称
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8001/eureka/
    management:
      endpoints:
        web:
          exposure:
            include: 'refresh'
    
  3. 以boostrap-cluster.yml为配置文件启动config-client服务,此时注册中心显示如下
    《Spring Cloud Config 实现配置中心及自动刷新》

  4. 访问http://localhost:9003/configInfo,发现config-client可以获取到配置信息,说明集群搭建是没问题的

FAQ

  • config-client启动一直报 config.info无法注入?
    config-client模块的配置文件名称需要为bootstrap.yml

总结

配置中心在微服务架构中是很重要的一环,可以非常方便的降低我们的运维成本,提高效率。从一开始的基础功能到慢慢的丰富 基础配置中心-》目录配置读取-》手动刷新配置-》安全认证-》集群搭建,每一步的发展都是由历史原因的,其它的技术也是一样。

附件

    原文作者:我思知我在
    原文地址: https://blog.csdn.net/qq_32828253/article/details/113528854
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞