Config配置中心
在分布式系统中,每个服务都有一个单独的配置,服务增多的情况下,配置文件会变得非常多,维护配置文件比较麻烦。所以需要一套集中的、动态的配置管理设施是必不可少的。
Springcloud提供了一个ConfigServer来解决这个问题。
1.Config简介
1.是什么
Springcloud Config为微服务中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
其结构如上图。所有的配置中心在git上维护配置文,本地config服务与git上一致,然后客户端从config服务获取自己需要的配置。
2.结构
springcloud config分为server端和client端。配置服务器默认采用git来存储配置信息,这样有助于对环境配置进行版本管理,并且可以通过git客户端来方便的管理和访问配置内容。
server端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并且为客户端提供配置信息、加密\解密等访问接口。
客户端则是通过指定的配置中心来管理资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。
3.主要作用
1.集中管理配置文件
2.不同环境不同配置,动态化的配置更新,分环境部署,比如dev\test\prod\beta\release
3.运行期间动态调整,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息。
4.当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置
5.将配置信息以REST接口的形式暴露
2.使用
1.github搭建配置文件项目
master分支和dev分支各有三个文件,如下:
(1)master/config-dev.yml
config:
info: master-dev,版本:1
(2)master/config-prod.yml
config:
info: master-prod,版本:1
(3)master/config-test.yml
config:
info: master-test,版本:1
(4)dev/config-dev.yml
config:
info: dev-dev,版本:1
(5)dev/config-prod.yml
config:
info: dev-prod,版本:1
(6)dev/config-test.yml
config:
info: dev-test,版本:1
2.新建cloud-config-center-3344子模块
1.新建moudle
2.修改pom
<?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>cloud</artifactId> <groupId>cn.qz.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-config-center-3344</artifactId> <dependencies> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <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> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
3.修改yml
server:
port: 3344
spring:
application:
name: cloud-config-center #注册进Eureka服务器的微服务名
cloud:
config:
server:
git:
uri: https://github.com/qiao-zhi/springcloud-config.git #GitHub上面的git仓库名字
####搜索目录
search-paths:
- springcloud-config
# 默认的分支,如果不配置的话默认是master分支
# default-label: dev
# username: 公有的不需要账号密码
# password: 公有的不需要账号密码
####读取分支
label: master
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
4.主启动类:
package cn.qz.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; /** * @Author: qlq * @Description * @Date: 22:44 2020/10/21 */ @SpringBootApplication @EnableConfigServer public class ConfigCenterMain3344 { public static void main(String[] args) { SpringApplication.run(ConfigCenterMain3344.class, args); } }
5.启动后访问测试:默认读取的是master分支,可以修改。
hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master) $ curl -X GET http://localhost:3344/config-prod.yml % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 41 100 41 0 0 10 0 0:00:04 0:00:03 0:00:01 10config: info: master-prod,版本:1 hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master) $ curl -X GET http://localhost:3344/master/config-prod.yml % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 41 100 41 0 0 25 0 0:00:01 0:00:01 --:--:-- 25config: info: master-prod,版本:1 hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master) $ curl -X GET http://localhost:3344/dev/config-prod.yml % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 38 100 38 0 0 33 0 0:00:01 0:00:01 --:--:-- 33config: info: dev-prod,版本:1
补充:springcloud有一套自己的访问规则,如下:
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
{application} 就是应用名称,对应到配置文件上来,就是配置文件的名称部分。比如对应config。
{profile} 就是配置文件的版本,我们的项目有开发版本、测试环境版本、生产环境版本,dev、prod、test等。
{label} 表示 git 分支,默认是 master 分支,如果项目是以分支做区分也是可以的,那就可以通过不同的 label 来控制访问不同的配置文件了。
例如:以/{application}/{profile}[/{label}]方式访问:
hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master) $ curl -X GET http://localhost:3344/config/prod % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 266 0 266 0 0 200 0 --:--:-- 0:00:01 --:--:-- 200{"name":"config","profiles":["prod"],"label":null,"version":"9fbb23c5f96fb32a9a99ee5c10480abd443f9ab0","state":null,"propertySources":[{"name":"https://github.com/qiao-zhi/springcloud-config.git/config-prod.yml","source":{"config.info":"master-prod,版本:1"}}]} hyyd@HYYD-M905AEEE MINGW64 /f/IDEASPACE/springcloud (master) $ curl -X GET http://localhost:3344/config/prod/dev % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 264 0 264 0 0 234 0 --:--:-- 0:00:01 --:--:-- 234{"name":"config","profiles":["prod"],"label":"dev","version":"24102d09cce20c48fafac63445624ec1b8c2b433","state":null,"propertySources":[{"name":"https://github.com/qiao-zhi/springcloud-config.git/config-prod.yml","source":{"config.info":"dev-prod,版本:1"}}]}
3.建立cloud-config-client-3355项目
该模块从上面3344服务端拿取自己的配置文件。
1.新建子模块
2.修改pom:
<?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>cloud</artifactId> <groupId>cn.qz.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-config-client-3355</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!--引入自己抽取的工具包--> <dependency> <groupId>cn.qz.cloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--监控--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--eureka client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</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> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
3.新建bootstrap.yml
server:
port: 3355
spring:
application:
name: config-client
cloud:
#Config客户端配置
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上诉3个综合就是 master分支上 config-dev.yml
uri: http://localhost:3344
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
补充:bootstrap.yml和application.yml的区别
applicaiton.yml是用户级的资源配置项,bootstrap.yml是系统级的,优先级更高。
Springcloud会创建一个"Bootstrap Context",作为Spring应用的"Application Context"的上下文。初始化的时候,BootstrapContext负责从外部源加载配置属性并解析配置。这两个上下文共享一个外部的Environment。
bootstrap.yml通常用于“使用Spring Cloud Config Server时,应在bootstrap.yml中指定spring.application.name和spring.cloud.config.server.git.uri”以及一些加密/解密信息。例如,当使用Spring Cloud时,通常从服务器加载“real”配置数据。为了获取URL(和其他连接配置,如密码等),您需要一个较早的或“bootstrap”配置。因此,您将配置服务器属性放在bootstrap.yml中,该属性用于加载实际配置数据(通常覆盖application.yml [如果存在]中的内容)。
另外,由于application.yml后加载,所以如果有相同属性的情况下,会以application.yml的为准。而且两个文件可以用${varname}互相取文件中的变量。
4.新建主启动类:
package cn.qz.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class ConfigClientMain3355 { public static void main(String[] args) { SpringApplication.run(ConfigClientMain3355.class, args); } }
5.新建controller
package cn.qz.cloud.controller; import cn.qz.cloud.utils.JSONResultUtil; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ConfigClientController { @Value("${config.info}") private String configInfo; @Value("${server.port}") private String serverPort; @GetMapping("/configInfo") public JSONResultUtil<String> configInfo() { String result = "serverPort: " + serverPort + ";configInfo: " + configInfo; return JSONResultUtil.successWithData(result); } }
6.测试
liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl http://localhost:3355/configInfo % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 100 0 100 0 0 3225 0 --:--:-- --:--:-- --:--:-- 6666{ "success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: maste r-dev,版本:1"} liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl http://localhost:3344/config-dev.yml % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 40 100 40 0 0 2 0 0:00:20 0:00:17 0:00:03 10config: info: master-dev,版本:1
3.存在的问题
git上修改配置之后,都不重启服务的情况下。3344server可以及时更新,3355客户端不能及时更新
1.上面从github上面修改master/config-dev.yml
config:
info: master-dev,版本:2
2.测试:
liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl http://localhost:3344/config-dev.yml % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 40 100 40 0 0 2 0 0:00:20 0:00:18 0:00:02 10config: info: master-dev,版本:2 liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl http://localhost:3355/configInfo % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 100 0 100 0 0 3225 0 --:--:-- --:--:-- --:--:-- 97k{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:1"}
发现3344可以及时更新,3355只有重启之后才可以更新。
3.解决办法:通过配置可以手动触发刷新
(1)修改bootstrap.yml
server: port: 3355 spring: application: name: config-client cloud: #Config客户端配置 config: label: master #分支名称 name: config #配置文件名称 profile: dev #读取后缀名称 上诉3个综合就是 master分支上 config-dev.yml uri: http://localhost:3344 eureka: client: service-url: defaultZone: http://localhost:7001/eureka/ # 暴露监控端点(可以暴露健康状态等,这里暴露所有) management: endpoints: web: exposure: include: "*"
(2)修改Controller,增加@RefreshScope注解
(3)重启之后查看:
liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl http://localhost:3355/configInfo % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 100 0 100 0 0 917 0 --:--:-- --:--:-- --:--:-- 1063{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:2"}
(4)git上面修改config-dev.yml
liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl http://localhost:3355/configInfo % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 100 0 100 0 0 917 0 --:--:-- --:--:-- --:--:-- 1063{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:2"}
(5)查看3344和3355配置
liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl http://localhost:3344/config-dev.yml % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 40 100 40 0 0 1 0 0:00:40 0:00:21 0:00:19 12config: info: master-dev,版本:3 liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl http://localhost:3355/configInfo % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 100 0 100 0 0 3225 0 --:--:-- --:--:-- --:--:-- 6250{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:2"}
发现3355还是没有自动同步
(6)手动访问URL触发更新
liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl -X POST http://localhost:3355/actuator/refresh % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 39 0 39 0 0 0 0 --:--:-- 0:00:43 --:--:-- 11["config.client.version","config.info"] liqiang@root MINGW64 /e/IDEAWorkSpace/cloud (master) $ curl http://localhost:3355/configInfo % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 100 0 100 0 0 3225 0 --:--:-- --:--:-- --:--:-- 6666{"success":true,"code":"200","msg":"","data":"serverPort: 3355;configInfo: master-dev,版本:3"}
通过上面的设置,改动完git上配置之后需要手动通过post请求通知服务刷新配置。当然如果服务增多的情况可以通过批处理脚本批量通知。
仍然不是一个较好的解决方案,因此需要引入springcloud Bus消息总线。