在微服务中,如果使用传统的方式管理配置文件,每个项目都有各自的配置文件,整个微服务系统的配置文件管理变得复杂。如果生产环境配置文件需要发生改变,需要重新打包,重新读取配置信息在JVM内存中。
个人理解:配置文件读取一般是在项目启动的时候去读取配置项的值并加载到jvm内存中,一旦启动之后,配置项值发生改变,想要让配置项生效,以前的做法只能是重启服务,分布式配置中心就是为了不重启服务器还能刷新配置项的值而产生的!
在微服务中使用同一个服务器管理所有服务配置文件信息,能实现后台可管理,当服务器正在运行的时候,如果配置文件需要发生改变,可以实现不需要重启服务器就能实时更新配置文件
(1)携程的Apollo,有图形界面可管理配置中心,配置文件信息存放在数据库
Apollo搭建分布式配置中心: https://blog.csdn.net/z960339491/article/details/80667559
(2)Spring Cloud Config 没有后台可以管理分布式配置中心,配置文件信息存放在版本控制器里面(git,svn)
(3)Zookeeper实现分布式配置中心(实现原理:持久节点+事件通知)
如图,springcloud分布式配置中心包含以下组成部分:
传统的项目,当一个系统中的配置文件发生改变的时候,我们需要重新启动该服务,才能使得新的配置文件生效,spring cloud config可以实现微服务中的所有系统的配置文件的统一管理,而且还可以实现当配置文件发生变化的时候,系统会自动更新获取新的配置。
看前面的图,用户推送配置文件到远程仓库Git,ConfigServer拉取Git仓的配置文件,并缓存到本地(ConfigServer的作用就是缓存远程仓的配置信息), user服务,product服务,order服务作为ConfigClient(ConfigServer的客户端),从ConfigServer读取配置信息,当远程仓配置有更新的时候,ConfigClient端通过调用接口的方式,刷新并获取最新的配置信息。
使用码云作为git远程仓库,存放项目的配置信息
新仓是空的,把仓库clone到本地,然后随便提交一个文件上去,然后新建文件夹——git环境上的文件根据项目进行区分,就是说,不要把不同项目的所有配置文件都放到同一个目录下
点击后输入文件夹名称然后提交:
<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.0modelVersion>
<groupId>com.lchtestgroupId>
<artifactId>springcloud2.0-config-serverartifactId>
<version>0.0.1-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.3.RELEASEversion>
parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Finchley.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-serverartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
dependencies>
project>
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
spring:
application:
#configserver在注册中心的应用名称
name: config-server
cloud:
config:
server:
git:
###git环境地址
uri: https://gitee.com/liuch890228/distributed_profile_learning.git
####搜索目录,自己在码云上的工程的仓库里面创建的目录名称
search-paths:
- configtest
#读取的配置的分支
label: master
# 码云创建仓库时选择的是公开,这里不用配置密码
#configserver服务的端口号
server:
port: 8888
package com.lchtest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* 分布式配置中心的ConfigServer
* @author pc
* 1.@EnableConfigServer注解开启config server
* 2.先启动eureka注册中心,再启动AppConfigServer
* 3.如何把配置文件存放到git上:
*/
@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer
public class AppConfigServer {
public static void main(String[] args) {
SpringApplication.run(AppConfigServer.class, args);
}
}
点击这个目录,新建文件,
创建 一个配置文件test-configClient-sit.properties,输入配置并提交
提交结果:
同理创建一个test-configClient-prd.properties配置文件,配置项相同,值不同:
依次启动eurekaServer和configServer,在浏览器输入访问
http://localhost:8888/test-configClient-prd.properties,可以读取到配置信息
<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.0modelVersion>
<groupId>com.lchtestgroupId>
<artifactId>springcloud2.0-config-clientartifactId>
<version>0.0.1-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.3.RELEASEversion>
parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Finchley.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
dependencies>
project>
spring:
application:
#注册中心应用名称
name: test-configClient
cloud:
config:
#读取的版本,通过后缀确定是开发环境or测试环境or生产环境
profile: prd
discovery:
#读取config-server在注册中心上注册的别名
service-id: config-server
#开启读取权限
enabled: true
#eureka服务注册地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
server:
port: 8882
配置文件中,需要注意spring.application.name 值是码云上面的配置文件名称中的服务名,Spring.cloud.config.profile的值是码云上面配置文件的开发/测试/生产环境标识,如下图所示:
package com.lchtest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class AppConfigClient {
public static void main(String[] args) {
SpringApplication.run(AppConfigClient.class, args);
}
}
package com.lchtest.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
//从configserver读取配置
@Value("${testconfigInfo}")
private String testconfigInfo;
@RequestMapping("/getConfigValue")
public String getConfigValue() {
return "configClient读取到的配置:testconfigInfo=" + testconfigInfo;
}
}
在启动eurekaServer和configServer项目的前提下,启动configClient项目,浏览器访问
http://localhost:8882/getConfigValue ,结果如下,顺利读取到配置项的值:
修改码云配置文件值
浏览器再去请求http://localhost:8882/getConfigValue,发现配置项还是原来的值这是因为:
1 默认情况下,修改了配置文件的内容,再去调用访问 /getConfigValue接口,是不能获取到最新的配置项的值的,并且configclient也会有缓存,除非重启configclient服务;
2.SpringCloud分布式配置中心可以采用手动刷新或者自动刷新,两者都不需要重启服务器
手动刷新——需要人工调用接口,读取最新配置文件(监控中心)
自动刷新——消息总线进行实时通知(springbus)
在实际使用过程中,不建议使用自动刷新功能,对性能有影响,建议每次修改了配置之后,人工调用/actuator/refresh接口进行刷新
(1)Configclient工程pom加入actuator依赖:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
(2)配置文件增加配置项:
#开启所有端点
management:
endpoints:
web:
exposure:
include: "*"
(3)controller中加上@RefshScope注解
重启启动AppConfigClient服务,可以发现启动时有一个接口/actuator/refresh,只要调用这个接口,就可以手动刷新配置文件了,需要注意的是这个接口是post请求:
通过postman向接口/actuator/refresh发送刷新请求:
在浏览器再去访问,可以看到配置项的值被刷新了
本文代码地址
springcloud2.0-config-client
springcloud2.0-config-server
以及springcloud2.0-eureak-server (单注册中心)