Spring Cloud学习笔记21——微服务的集中化配置(Config)

微服务为什么需要集中化配置

一般应用中都会有配置文件,即便是号称“零配置”的Spring Boot应用,也无法完全做到不使用配置文件,因为配置文件是为了迎合软件的一些个性化需求,所以说应用程序是无法避免这种配置的,特别是在微服务系统架构中,应用程序往往会部署在多个实例上,每个实例都有各自的不同的配置,如果配置发生了更改,每个服务实例都需要进行配置的变更,既然配置的变更无法避免,每个微服务自己的配置文件散落在自己的应用中,必然会对应用的配置和升级带来挑战,故而需要引入集中化配置,来解决微服务中关于配置的问题。

  • 微服务数量多,配置多
  • 手工管理配置繁琐

配置分类

  • 按配置的来源划分:主要有源代码、文件、数据库连接、远程调用等
  • 按配置的环境划分:开发环境、测试环境、预发布环境、生产环境等
  • 按配置的集成阶段划分:编译时、打包时和运行时
  • 按配置的加载方式划分:启动加载和动态加载

配置中心的要求

  • 面向可配置的编码:在创建符合要求、易于使用的配置中心时,在编码过程中,应及早考虑后期可能会经常变更的一些数据,设置为可以配置的配置项,可避免在代码中硬编码
  • 隔离性:不同的部署环境,应用之间的配置是相互隔离的
  • 一致性:相同的部署的服务器的应用配置应该是一致的,在相同部署环境下,同一个应用的所有实例使用同一份配置
  • 集中化配置:在分布式环境下,应用的配置应该具备可管理性,即提供远程管理的能力

配置中心的文件命名规则

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

Spring Cloud Config

Spring Cloud ConfigSpring Cloud团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端与客户端两个部分。

其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密/解密信息等访问接口;而客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。

Spring Cloud Config实现了对服务端和客户端中环境变量和属性配置的抽象映射,所以它除了适用于Spring构建的应用程序之外,也可以在任何其他语言运行的应用程序中使用。由于Spring Cloud Config实现的配置中心默认采用Git来存储配置信息,所以使用Spring Cloud Config构建的配置服务器,天然就支持对微服务应用配置信息的版本管理,并且可以通过Git客户端工具来方便地管理和访问配置内容。当然它也提供了对其他存储方式的支持,比如SVN仓库,本地化文件系统。

分布式外部化配置

  • Config Server:管理应用程序的外部属性,底层实现基于Git
  • Config Client

Spring Cloud Config服务端的基础架构:

  • 远程Git仓库:用来存储配置文件的地方。
  • Config Server:构建的分布式配置中心,config-server工程,在该工程中指定了所要连接的Git仓库位置以及账户、密码等连接信息。
  • 本地Git仓库:在Config Server的文件系统中,每次客户端请求获取配置信息时,Config ServerGit仓库中获取最新配置到本地,然后在本地Git仓库中读取并返回。当远程仓库无法获取时,直接将本地内容返回。
  • Service AService B:具体的微服务应用,它们指定了Config Server的地址,从而实现从外部化获取应用自己要用的配置信息。这些应用在启动的时候,会向Config Server请求获取配置信息来进行加载。
    Spring Cloud学习笔记21——微服务的集中化配置(Config)_第1张图片

客户端应用从配置管理中获取配置信息遵从下面的执行流程:

  1. 应用启动时,根据bootstrap.properties中配置的应用名{application}、环境名{profile}、分支名{label},向Config Server请求获取配置信息。
  2. Config Server根据自己维护的Git仓库信息和客户端传递过来的配置定位信息去查找配置信息。
  3. 通过git clone命令将找到的配置信息下载到Config Server的文件系统中。
  4. Config Server创建SpringApplicationContext实例,并从Git本地仓库中加载配置文件,最后将这些配置内容读取出来返回给客户端应用。
  5. 客户端应用在获得外部配置文件后加载到客户端的ApplicationContext实例,该配置内容的优先级高于客户端Jar包内部的配置内容,所以在Jar包中重复的内容将不再被加载。

Config Server巧妙地通过git clone将配置信息存于本地,起到了缓存的作用,即使当Git服务端无法访问的时候,依然可以取Config Server中的缓存内容进行使用。

我的GitHub

Spring Cloud学习笔记21——微服务的集中化配置(Config)_第2张图片
Spring Cloud学习笔记21——微服务的集中化配置(Config)_第3张图片

使用Config实现配置中心Server端

开发环境

  • JDK8+
  • Gradle4+
  • Spring Boot 2.0.0.M3
  • Spring Cloud Starter Netflix Eureka Client Finchley.M2
  • Spring Cloud Config Server Finchley.M2

创建项目

以之前的micro-weather-eureka-client为蓝本,创建micro-weather-config-server项目
Spring Cloud学习笔记21——微服务的集中化配置(Config)_第4张图片

修改源码

修改build.gradle配置,添加Spring Cloud Config Server依赖:

//buildscript代码块中脚本优先执行
buildscript {

    //ext用于定义动态属性
	ext {
		springBootVersion = '2.0.0.M3'
	}

    //使用了Maven的中央仓库及Spring自己的仓库(也可以指定其他仓库)
	repositories {
		//mavenCentral()
        maven{ url "https://repo.spring.io/snapshot" }
        maven{ url "https://repo.spring.io/milestone" }
        maven{ url "http://maven.aliyun.com/nexus/content/groups/public/" }
	}

    //依赖关系
	dependencies {
        //classpath声明了在执行其余的脚本时,ClassLoader可以使用这些依赖项
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

//使用插件
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

//指定了生成的编译文件的版本,默认是打成了jar包
group = 'com.study.spring.cloud'
version = '1.0.0'

//指定编译.java文件的JDK版本
sourceCompatibility = 1.8

//使用了Maven的中央仓库及Spring自己的仓库(也可以指定其他仓库)
repositories {
    //mavenCentral()
    maven{ url "https://repo.spring.io/snapshot" }
    maven{ url "https://repo.spring.io/milestone" }
    maven{ url "http://maven.aliyun.com/nexus/content/groups/public/" }
}

ext {
    springCloudVersion = 'Finchley.M2'
}

//依赖关系
dependencies {

    //Eureka Client
    compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')

    //Spring Cloud Config Server
    compile('org.springframework.cloud:spring-cloud-config-server')

    //该依赖用于测试阶段
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

//Spring Cloud依赖管理
dependencyManagement{
    imports{
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

修改com.study.spring.cloud.weather包下的Application类,加入@EnableConfigServer注解:

package com.study.spring.cloud.weather;

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;

/*
 * @SpringBootApplication注解声明Spring Boot应用
 * 作用等同于@Configuration, @EnableAutoConfiguration, @ComponentScan,
 * 简化Spring配置
*/
@SpringBootApplication
//启用可发现的客户端
@EnableDiscoveryClient
//启用Config Server
@EnableConfigServer
//Application类一定要处于整个工程的根目录下,这样它才能根据配置去扫描子节点下的Spring的Bean
public class Application {

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

修改application.properties配置文件:

#应用名称
spring.application.name=micro-weather-config-server

#指定端口
server.port=8888

#注册服务器的URL
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

#GitHub仓库
spring.cloud.config.server.git.uri=https://github.com/yehongliu/config-server-study.git

#下级目录
spring.cloud.config.server.git.search-paths=config-repo

先运行micro-weather-eureka-server,再运行micro-weather-config-server,运行结果如下:
Spring Cloud学习笔记21——微服务的集中化配置(Config)_第5张图片
访问http://localhost:8888/auther/dev页面:
在这里插入图片描述

使用Config实现配置中心Client端

开发环境

  • JDK8+
  • Gradle4+
  • Spring Boot 2.0.0.M3
  • Spring Cloud Starter Netflix Eureka Client Finchley.M2
  • Spring Cloud Config Client Finchley.M2

创建项目

以之前的micro-weather-eureka-client为蓝本,创建micro-weather-config-client项目
Spring Cloud学习笔记21——微服务的集中化配置(Config)_第6张图片

修改源码

修改build.gradle配置,添加Spring Cloud Config Client依赖:

//依赖关系
dependencies {

    //Eureka Client
    compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')

    //Spring Cloud Config Client
    compile('org.springframework.cloud:spring-cloud-config-client')

    //该依赖用于测试阶段
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

修改application.properties配置文件:

#应用名称
spring.application.name=micro-weather-config-client

#注册服务器的URL
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

#指定环境
spring.cloud.config.profile=dev

#指向Config Server
spring.cloud.config.uri=http://localhost:8888/

运行测试

修改test下的com.study.spring.cloud.weather包下的ApplicationTests类:

package com.study.spring.cloud.weather;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.assertEquals;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {

	@Value("${auther}")
	private String auther;

	@Test
	public void contextLoads() {
		assertEquals("willow51",auther);
	}

}

先运行micro-weather-eureka-servermicro-weather-config-server,再运行ApplicationTests类的contextLoads测试方法,运行结果如下:
Spring Cloud学习笔记21——微服务的集中化配置(Config)_第7张图片

你可能感兴趣的:(Spring,Cloud)