1.开发中的实际问题
着线上项目变的日益庞大,每个项目都散落着各种配置文件,如果采用分布式的开发模式,需要的配置文件随着服务增加而不断增多。某一个基础服务信息变更,都会引起一系列的更新和重启,运维苦不堪言也容易出错。配置中心便是解决此类问题的灵丹妙药。
市面上开源的配置中心有很多,BAT每家都出过,360的QConf、淘宝的diamond、百度的disconf都是解决这类问题。国外也有很多开源的配置中心Apache的Apache Commons Configuration、owner、cfg4j等等。这些开源的软件以及解决方案都很优秀,但是Spring Cloud Config,因为它功能全面强大,可以无缝的和spring体系相结合,够方便够简单颜值高。
2.什么是 spring cloud config
在我们了解spring cloud config之前,我们可以想想一个配置中心提供的核心功能应该有什么
提供服务端和客户端支持—>服务端
集中管理各环境的配置文件
配置文件修改之后,可以快速的生效
可以进行版本管理
支持大的并发查询
支持各种语言
Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。Spring cloud使用git或svn存放配置文件,默认情况下使用git
3.本地环境配置
3.1 server端配置
3.1.1 创建项目,引入依赖
!--
加入eureka客户端依赖 将配置中心(config)注册到eureka上
让eureka来管理 ip和端口号 eureka 可以做一个配置中心的集群
eureka会帮我们自动做负载均衡
一旦某台config配置中心 宕机 不影响程序的运行
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--标注当前工程是 config 服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
3.1.2 application.yml配置
server:
port: 9900
spring:
application:
name: shop-config-server
# 配置使用本地存储
profiles:
active: native
# 本地配置文件的存储路径
cloud:
config:
server:
native:
search-locations: classpath:properties/ # src/main/resource 下的properties文件夹下的文件
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka
3.1.3 创建properties文件夹下的文件
person.name=***
# Redis配置
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
# jpa 配置
spring.jpa.database=MYSQL
# 是否创建更新表
spring.jpa.generate-ddl=true
# 是否打印sql
spring.jpa.show-sql=true
# 数据库连接配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring_cloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
# eureka 配置管理的ip可见
eureka.instance.prefer-ip-address=true
eureka.instance.hostName=${spring.cloud.client.ip-address}
eureka.instance.instance-id=http://${spring.cloud.client.ip-address}:${server.port}
# ribbon 配置
# 请求连接超时时间
ribbon.ConnectTimeout=5000
# 请求处理的超时时间 单位毫秒
ribbon.ReadTimeout=5000
3.1.4 创建启动类
加入@EnableConfigServer注解,标注当前是config的服务端
@SpringBootApplication
@EnableDiscoveryClient
//标注当前是config的服务端
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class);
}
}
3.1.5 测试
启动服务端,访问
http://localhost:9900/shop-config/dev
9900:服务端口号

可以看到,我们通过接口访问到了配置信息。
3.2 client配置(客户端)
3.2.1 加入依赖
<!--config的客户端的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
3.2.1 配置bootstrap.yml
注意:因为我们是从config配置中心获取配置信息的,这里使
bootstrap.yml,让程序启动首先加载bootstrap.yml文件,就获取到config配置中心的地址,去获取配置信息,不能使用application.yml,因为它是在程序启动中加载的。
server:
port: 9000
spring:
application:
name: shop-user
cloud:
config:
name: shop-config
profile: dev
discovery:
# config配置发现已启用
enabled: true
# 配置中心的唯一标识
service-id: shop-config-server
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka
3.2.2 启动类
@SpringBootApplication
@EnableDiscoveryClient
//开启熔断
@EnableCircuitBreaker
public class UserShopApplication {
public static void main(String[] args) {
SpringApplication.run(UserShopApplication.class);
}
}
注意:这里的我加了熔断,不用管,可以不加,直接启动
3.2.3 验证客户端是否能从config服务端读取到配置信息
我这里了
服务端的端口号:9900

客户端的端口号:
9000,可以看到,客户端获取到了配置信息启动起来了

4.GIT配置环境
4.1 server端配置
首先在gitee上面创建了一个仓库,然后在分支下创建一个文件夹shop-config用来存放配置文件,为了模拟生产环境,我们创建以下三个配置文件:
// 开发环境
shop-config-dev.properties
// 测试环境
shop-config-test.properties
// 生产环境
shop-config-pro.properties
4.1.1 添加依赖
<!--标注当前工程是 config 服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
4.1.2 配置application.yml文件
server:
port: 9900
spring:
application:
name: shop-config-server
# 配置使用本地存储
# profiles:
# active: native
cloud:
config:
server:
git:
uri: https://gitee.com/****/config.git #配置git仓库地址
default-label: master #对应git的分支 即配置文件所在的分支,默认是master分支时,可以不配置
search-paths: shop-config # (分支下的文件夹)git仓库地址下的相对地址,可以配置多个,用,分割。
# native:
# search-locations: classpath:properties/ # src/main/resource 下的propertie文件夹下的文件
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka
4.1.3 启动类
启动类添加@EnableConfigServer,激活对配置中心的支持
@SpringBootApplication
@EnableDiscoveryClient
//标注当前是config的服务端
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class);
}
}
到此server端相关配置已经完成,服务端的端口号:9900
4.1.3 测试服务是能获取git上的配置文件
访问:
http://localhost:9900/shop-config/dev

上述的返回的信息包含了配置文件的位置、版本、配置文件的名称以及配置文件中的具体内容,说明server端已经成功获取了git仓库的配置信息。
4.2 client端配置
与本地配置的步骤相同
4. refresh 刷新 动态获取配置
4.1 refresh 刷新
Spring Cloud Config分服务端和客户端,服务端负责将git(svn)中存储的配置文件发布成REST接口,客户端可以从服务端REST接口获取配置。但客户端并不能主动感知到配置的变化,从而主动去获取新的配置。客户端如何去主动获取新的配置信息呢,springcloud已经给我们提供了解决方案,每个客户端通过POST方法触发各自的/refresh,修改spring-cloud-config-client项目已到达可以refresh的功能。
当git上的配置文件发生改变时,客户端动态获取配置文件,不需要重新启动
4.1.1 添加依赖
<!--提供当前工程的状态等信息的包,同时提供refresh刷新功能,帮助我们进行自动的更新-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
增加了
spring-boot-starter-actuator包,spring-boot-starter-actuator是一套监控的功能,可以监控程序在运行时状态,其中就包括/refresh的功能。
4.1.2 修改git上的配置文件
加入:
# refresh 自动刷新 配置文件发生改变 客户端自动获取配置信息
management.endpoints.web.exposure.include=refresh
4.1.2 主动触发refresh 刷新
告诉当前客户端,配置文件刷新了
因为我这里配置的是shop-user服务,端口号:
9000
发送post请求:
http://localhost:9000/actuator/refresh
这里我们使用Postman测试
注意:当我们启动一个服务时,在启动中我们是不能发起请求的,或者说请求是会失败的,但是在我们主动触发refresh 刷新时,
程序在刷新中,是可以请求成功的。