分布式配置中心
一、Config分布式配置中心概述
1. 分布式系统面临的配置问题
到目前有多个微服务模块(9527/8001/8002/8003/7001/7002/7003…),每个微服务中都一个对应的yml文件,那么要是在公司中有上百个微服务项目,这样是不是给运营维护带来了非常大的压力了?
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。SpringCloud提供了ConfigServer来解决这个问题。
2. SpringCloud Config的介绍
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的环境提供了一个中心化的外部配置。
SpringCloud Config与Eureka一样分为服务端和客户端两部分。
- 服务端:称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,如加密/解密信息等访问接口
- 客户端:通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。
3. SpringCloud Config的好处
- 集中管理配置文件
- 不同环境不同配置,动态化的配置更新,分环境部署。比如dev/test/prod/beta/release…
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取自己对应的配置信息
- 当配置发生变动时,服务不需要重启即可感知到配置的变化,并自动的应用新的配置信息
- 将配置信息以REST接口的形式暴露
- 与Git整合配置,由于SpringCloud Config默认使用Git来存储配置文件(也有其它方式,比如支持SVN和本地文件),但最推荐的还是Git,而且使用的是http/https访问的形式
二、SpringCloud Config服务端配置
1. 建立git远程仓库
用自己的GitHub/Gitee账号新建一个名为springcloud-config的仓库
2. 获取仓库地址
地址:https://gitee.com/wangsen127/springcloud-config.git
3. clone到本地硬盘
git clone https://gitee.com/wangsen127/springcloud-config.git
4. 本地yml文件
在本地硬盘目录中新建一个application.yml文件,内容如下
spring:
profiles:
active:
- dev
---
# 开发环境
spring:
profiles: dev
application:
name: springcloud-config-dev
---
# 测试环境
spring:
profiles: test
application:
name: springcloud-config-test
注意:文件格式必须为UTF-8
5. 文件推送
将application.yml文件推送到gitee上
git add .
git commit -m "init yml"
git push origin master
6. 新建配置中心服务端模块
模块名称为:springcloud-config-server
7. pom.xml
<dependencies>
<!--config server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
8. yml文件
server:
port: 5001
spring:
application:
name: springcloud-config-server
cloud:
config:
server:
#Gitee上面的git仓库名字
git:
uri: https://gitee.com/wangsen127/springcloud-config.git
9. 主启动类
@SpringBootApplication
//开启配置服务
@EnableConfigServer
public class SpringcloudConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudConfigServerApplication.class, args);
}
}
10. 测试
测试通过Config微服务是否可以从Gitee上获取配置内容
- 启动配置中心服务端springcloud-config-server
配置读取规则如下:
-
/{application}-{profile}.yml
-
/{application}/{profile}[/{label}]
-
/{label}/{application}-{profile}.yml
三、SpringCloud Config客户端配置
1. 本地yml文件
在本地硬盘目录中新建一个springcloud-config-client.yml文件,内容如下。
编写完成后推送到gitee仓库中。
spring:
profiles:
active:
- dev
---
server:
port: 8201
spring:
profiles: dev
application:
name: springcloud-config-client
eureka:
client:
service-url:
defaultZone: http://eureka-dev.com:7001/eureka/
---
server:
port: 8202
spring:
profiles: test
application:
name: springcloud-config-client
eureka:
client:
service-url:
defaultZone: http://eureka-test.com:7001/eureka/
注意:文件格式必须为UTF-8
2. 配置中心客户端模块
模块名称为:springcloud-config-client
3. pom.xml
<dependencies>
<!--config-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
4. yml文件
4.1 bootstrap.yml
applicaiton.yml是用户级的资源配置项;bootstrap.yml是系统级的,优先级更加高。
Spring Cloud会创建一个Bootstrap Context,作为Spring应用的Application Context的父上下文。初始化的时候,Bootstrap Context负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的Environment。Bootstrap属性有高优先级,默认情况下,它们不会被本地配置覆盖。 Bootstrap context和Application Context有着不同的约定,所以新增了一个bootstrap.yml文件,保证Bootstrap Context和Application Context配置的分离。
spring:
cloud:
config:
#需要从gitee上读取的资源名称,注意没有yml后缀名
name: springcloud-config-client
#本次访问的配置项
profile: dev
label: master
#本微服务启动后先去找5001号服务,通过SpringCloudConfig获取Gitee的服务地址
uri: http://localhost:5001
4.2 application.yml
spring:
application:
name: springcloud-config-client
5. Controller类
验证是否能从Gitee上读取配置
@RestController
public class ConfigClientController {
@Value("${spring.application.name}")
private String applicationName;
@Value("${eureka.client.service-url.defaultZone}")
private String eurekaServer;
@Value("${server.port}")
private String port;
@RequestMapping("/getConfig")
public String getConfig(){
String str = "applicationName:" + applicationName + "\t eurekaServer:"
+ eurekaServer + "\t port:" + port;
return str;
}
}
6. 主启动类
@SpringBootApplication
public class SpringcloudConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudConfigClientApplication.class, args);
}
}
7. 测试
- 启动配置中心服务端springcloud-config-server
- http://localhost:5001/application-dev.yml
- 启动配置中心客户端springcloud-config-client
- 在gitee默认为dev开发模式,对应的端口就是8201
- http://localhost:8201/getConfig
- 修改目前是profile: test测试模式对应的端口就是8202
- http://localhost:8202/getConfig
四、本地配置
本地配置:表示可将配置中心管理的yml都放在Config Server的本地进行管理
1. 本地配置文件
springcloud-config-local.yml
spring:
profiles:
active:
- dev
---
server:
port: 8301
spring:
profiles: dev
application:
name: springcloud-config-client-local
eureka:
client:
service-url:
defaultZone: http://localhost-dev:7002/eureka/
---
server:
port: 8302
spring:
profiles: test
application:
name: springcloud-config-client-local
eureka:
client:
service-url:
defaultZone: http://localhost-test:7003/eureka/
2. config server
application.yml:
server:
port: 5001
spring:
application:
name: springcloud-config-server
profiles:
# 指定为native,开启本地存储配置的方式,spring cloud微服务配置中心默认为:远程git仓库
active: native
cloud:
config:
server:
# 本地配置文件
native:
search-locations: classpath:/config/
3. config client
spring:
cloud:
config:
# 资源名称,注意没有yml后缀名
name: springcloud-config-local
# 本次访问的配置项
profile: dev
# 本微服务启动后先去找端口号5001服务,通过Config Server获取配置
uri: http://localhost:5001
备注:config client每次可以读取多个配置文件,以逗号分隔即可。实际应用中可将各个微服务中重复的配置放入到公共文件内。
五、SpringCloud Config配置应用
1. 配置演示
- Config服务端配置成功且测试通过,可以和Gitee进行配置修改并获得内容
- 此时我们做一个Eureka服务+一个Dept访问的微服务,将两个微服务的配置统一由于gitee获得实现统一配置分布式管理,完成多环境的变更
2. Git本地文件配置
在本地目录中建立springcloud-config-client-eureka.yml文件,内容如下:
spring:
profiles:
active: dev
---
server:
port: 7001
spring:
profiles: dev
application:
name: springcloud-config-client-eureka
eureka:
instance:
hostname: eureka7001.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
---
server:
port: 7001
spring:
profiles: test
application:
name: springcloud-config-client-eureka
eureka:
instance:
hostname: eureka7001.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
在本地目录中建立springcloud-config-client-dept.yml文件,内容如下:
spring:
profiles:
active: dev
---
server:
port: 8001
spring:
profiles: dev
application:
name: springcloud-config-client-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/cloudDB01
username: root
password: 123456
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
type-aliases-package: com.springcloud.entity
mapper-locations: classpath:mybatis/mapper/**/*.xml
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka
instance:
instance-id: springcloud-dept8001
prefer-ip-address: true
info:
app.name: newcapec-springcloud
company.name: www.newcapec.com.cn
project.artifactId: springcloud-config-client-dept01
project.version: v1.0.1
---
server:
port: 8001
spring:
profiles: test
application:
name: springcloud-config-client-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/cloudDB02
username: root
password: 123456
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
type-aliases-package: com.springcloud.entity
mapper-locations: classpath:mybatis/mapper/**/*.xml
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka
instance:
instance-id: springcloud-dept8001
prefer-ip-address: true
info:
app.name: newcapec-springcloud
company.name: www.newcapec.com.cn
project.artifactId: springcloud-config-client-dept02
project.version: v1.0.1
3. Config版的Eureka服务端
3.1 新建Config版的Eureka服务端模块
模块名称:springcloud-config-client-eureka
3.2 pom.xml
<dependencies>
<!--config-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<!--eureka-server服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
3.3 yml文件
bootstrap.yml:
spring:
cloud:
config:
#需要从gitee上读取的资源名称,注意没有yml后缀名
name: springcloud-config-client-eureka
#本次访问的配置项
profile: dev
label: master
#本微服务启动后先去找5001号服务,通过SpringCloudConfig获取Gitee的服务地址
uri: http://localhost:5001
application.yml:
spring:
application:
name: springcloud-config-client-eureka
3.4 主启动类
@SpringBootApplication
//EurekaServer服务器端启动类,接受其它微服务注册进来
@EnableEurekaServer
public class ConfigClientEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientEurekaServerApplication.class, args);
}
}
3.5 测试
- 启动配置中心服务端springcloud-config-server,保证Config配置中心是OK的
- 启动配置中心客户端Eureka服务端springcloud-config-client-eureka
- 访问:http://eureka7001.com:7001/,出现Eureak主页表示成功启动
4. Config版的微服务提供者
4.1 新建Config版的微服务提供者模块
模块名称:springcloud-config-client-dept
4.2 pom.xml
<dependencies>
<!--config-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</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-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- 引入自己定义的api通用包,可以使用Dept部门Entity -->
<dependency>
<groupId>com.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
4.3 yml文件
bootstrap.yml:
spring:
cloud:
config:
#需要从gitee上读取的资源名称,注意没有yml后缀名
name: springcloud-config-client-dept
#本次访问的配置项
profile: dev
label: master
#本微服务启动后先去找5001号服务,通过SpringCloudConfig获取Gitee的服务地址
uri: http://localhost:5001
application.yml:
spring:
application:
name: springcloud-config-client-dept
4.4 主启动类
@SpringBootApplication
//本服务启动后会自动注册进eureka服务中
@EnableEurekaClient
@EnableDiscoveryClient
public class ConfigClientDeptProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientDeptProviderApplication.class, args);
}
}
4.5 配置说明
此微服务启动时先看bootstrap.yml文件里面的spring.cloud.config.profile属性具体值,从而确定它能从gitee上取得什么样的配置。
如果配置为dev,读取的数据库为clouddb01
如果配置为test,读取的数据库为clouddb02
每个环境的具体各自数据库不同,从而依据配置得到分布式配置的目的。
4.6 测试
- 本地换配置成dev
- http://localhost:8001/dept/list,可以看到数据库配置是01
- 本地换配置成test
- http://localhost:8001/dept/list,可以看到数据库配置是02