学习Spring Cloud 技术第七篇-服务配置

92 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情

相关阅读

  1. 带你学习Spring Cloud 技术第一篇-总览
  2. 带你学习Spring Cloud 技术第二篇-技术介绍
  3. 带你学习Spring Cloud 技术第三篇-服务注册中心
  4. 学习Spring Cloud 技术第四篇-服务调用
  5. 学习Spring Cloud 技术第五篇-服务降级
  6. 学习Spring Cloud 技术第六篇-服务网关

一、服务配置(Spring Cloud Config)

image.png

本文的开篇,首先介绍一下服务配置中心的定位。服务配置中心,也可以简称为配置中心。顾名思义,配置中心也就是维护整个服务项目配置的系统平台。分布式系统由于服务比较多,调用复杂,服务的配置、维护是一件十分耗时的事情,另外,还有不同的环境的配置,例如:开发环境、测试环境、生产环境等等。配置中心就是为了解决这个问题的。简化各种微服务的配置,采用统一化的方式维护整个服务的配置。

二、技术简述

参考文档:

cloud.spring.io/spring-clou…

github.com/spring-clou…

Spring Cloud Config 为分布式系统中的外部化配置提供了服务器端客户端支持。有了配置服务器,您就有了一个中心位置来管理跨所有环境的应用程序的外部属性。客户端和服务器上的概念与Spring的“环境”和“PropertySource”抽象完全相同,因此它们非常适合Spring应用程序,但也可以用于任何语言运行的任何应用程序。当应用程序通过部署管道从dev转移到测试和生产时,您可以管理这些环境之间的配置,并确保应用程序在迁移时拥有运行所需的一切。服务器存储后端的默认实现使用git,因此它很容易支持带标签的配置环境版本,并且可以访问用于管理内容的各种工具。添加替代实现并将其插入到Spring配置中是很容易的。

2.1 分布式系统面临的问题

配置文件的维护以及更新会需要大量的时间精力来维护,所以我们需要一个可以集中式、动态配置的管理设施是必不可少的。

2.2 配置中心是什么,有什么作用?

Spring Cloud Config 为微服务架构中的微服务提供了集中化的外部配置支持。配置的服务器为不同的微服务应用提供了一个中心化的外部配置。Spring Cloud Config为分布式系统中的外部化配置提供了服务器和客户端支持。通过配置服务器,您可以在所有环境中管理应用程序的外部属性。

2.3 Spring Cloud Config 能做什么?

集中管理配置文件:不同环境,不同配置,动态化配置更新、分环境进行部署,比如:dev\beta\prod\release。

运行期间,动态的调整配置,不需要在每一个服务部署的机器上面编写胚子文件,服务会想配置中心统一拉取的配置 自己的信息。

当配置发生变动的时候,服务不需要重启就可以感知配置的变化、并且直接应用新的配置。

将配置的信息用rest接口的形式进行暴露

三、代码实操

3.1 新增配置中心模块

新建一个module,命名为:spring-cloud-config-config3344

3.2 配置新建立的项目

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">
    <parent>
        <artifactId>spring-cloud-learn</artifactId>
        <groupId>com.breakpoint</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>

    <artifactId>spring-cloud-config-config3344</artifactId>

    <dependencies>
        <!--  spring-cloud-config-server 服务的配置中心   -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <!-- 以后所有的操作都是带有stater  -->
        <!--   netflix-eureka-client    -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--   引入spring-boot支持的依赖  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--  注意一下 要引入 starter 的  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

application.yml

server:
  port: 3344
spring:
  application:
    name: cloud-config-center # 注册进eureka的服务的名字
  cloud:
    config:
      label: master # 分支的名称
      server:
        git:
          uri: https://github.com/zhaoligang594/spring-cloud-config.git # 我们的git地址
          search-paths:
            - spring-cloud-config # 搜索的文件夹
# 服务的注册地址
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://peer1:7001/eureka/

3.3 启动类配置

/**
 * @author :breakpoint/赵立刚
 * @date : 2020/07/27
 */
@EnableConfigServer
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigCenter3344 {

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

3.4 测试结果

分别启动服务的注册中心7001以及当前的配置中心3344,配置中心注册到eureka的服务注册中心上。

image.png

3.5 多种获取配置方法

官方为我们提供了多种的请求的方式:

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

/{application}/{profile}[/{label}]

四、配置中心的客户端

之前的代码,仅仅是配置了一个管理所有配置的配置中心,如果某一个服务想要动态的从配置中心拿到配置信息。

4.1 新建模块

新建spring-cloud-config-client-3355 的模块,与上面创建的过程大致相同。

4.2 项目配置

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">
    <parent>
        <artifactId>spring-cloud-learn</artifactId>
        <groupId>com.breakpoint</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>

    <artifactId>spring-cloud-config-client-3355</artifactId>

    <dependencies>
        <!--  添加消息总线的支持   -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>

        <!--  客户端的配置方式  -->
        <!--  spring-cloud-config 服务的配置中心  注意与服务的配置中心引入的是不同的依赖  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <!-- erureka-->
        <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>
        <!--  注意一下 要引入 starter 的  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

bootstarp.yml

server:
  port: 3355
spring:
  application:
    name: cloud-config-client
  cloud:
    config:
      label: master  # label
      name: config   # name
      profile: dev   # 哪一个
      uri: http://config:3344 # 合在一起:http://config:3344/master/config-dev.yml
eureka:
  client:
    service-url:
      defaultZone: http://peer1:7001/eureka/
# 下面属于动态刷新的部分
management:
  endpoints:
    web:
      exposure:
        include: "*"
# 之后配合 @RefreshScope
#用 curl -X POST "http://localhost:3355/actuator/refresh" 手动进行刷新

4.3 代码启动类

/**
 * @author :breakpoint/赵立刚
 * @date : 2020/07/27
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ConfigClient3355 {

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

4.4 新增业务类

/**
 * @author :breakpoint/赵立刚
 * @date : 2020/07/27
 */
@RestController
public class TestController {

    @Value("${config.info}")
    private String configInfo;


    @GetMapping("/getConfigInfo")
    public String getConfigInfo() {
        return "from config client,config info is" + configInfo;
    }

}

4.5 测试运行

image.png

五、其他的问题(配置的更新)

虽然,已经配置好了我们的客户端,配置中心的功能是统一的维护我们的配置的信息,但是假设每次修改一次配置信息,就要重新修改一次,是不是会造成一些意想不到的问题呢?

修改业务类

@RefreshScope // 加上可以更新的注解
@RestController
public class TestController {

    @Value("${config.info}")
    private String configInfo;


    @GetMapping("/getConfigInfo")
    public String getConfigInfo() {
        return "from config client,config info is" + configInfo;
    }

}

修改github上的数据

image.png

测试配置中心

image.png

通过上面的配置,可以发现,配置中心是实时更新的。

客户端测试

image.png

发现客户端没有变化。

** 使用命令更新:**

curl -X POST "http://localhost:3355/actuator/refresh"

image.png

查看后台的打印:

image.png

访问,观察更新结果:

image.png

六、后记

想要更新我们的配置,达到了不用重新启动我们的服务,但是还是存在一个问题。如果服务存在成千上万个,那是不是导致了不必要的成本,那么在 消息总线 可以解决这个问题的。

七、相关阅读

  1. 带你学习Spring Cloud 技术第一篇-总览
  2. 带你学习Spring Cloud 技术第二篇-技术介绍
  3. 带你学习Spring Cloud 技术第三篇-服务注册中心
  4. 学习Spring Cloud 技术第四篇-服务调用
  5. 学习Spring Cloud 技术第五篇-服务降级
  6. 学习Spring Cloud 技术第六篇-服务网关

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情