SpringCloud Config
1 配置中心概述
1.1 配置中心简介
对于传统的单体应用而言,常使用配置文件来管理所有配置,比如SpringBoot的application.yml文件,但是在微服务架构中全部手动修改的话很麻烦而且不易维护。微服务的配置管理一般有以下需求:
- 集中配置管理,一个微服务架构中可能有成百上千个微服务,所以集中配置管理是很重要的。
- 不同环境不同配置,比如数据源配置在不同环境(开发,生产,测试)中是不同的。
- 运行期间可动态调整。例如,可根据各个微服务的负载情况,动态调整数据源连接池大小等
- 配置修改后可自动更新。如配置内容发生变化,微服务可以自动更新配置
综上所述对于微服务架构而言,一套统一的,通用的管理配置机制是不可缺少的总要组成部分。常见的做法就是通过配置服务器进行管理。
1.2 常见配置中心
Spring Cloud Config 为分布式系统中的外部配置提供服务器和客户端支持。
Apollo(阿波罗) 是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
Disconf 专注于各种「分布式系统配置管理」的「通用组件」和「通用平台」, 提供统一的「配置管理服务」包括 百度、滴滴出行、银联、网易、拉勾网、苏宁易购、顺丰科技 等知名互联网公司正在使用! 「disconf」在「2015 年度新增开源软件排名 TOP 100(OSC开源中国提供)」中排名第16强。Disconf的功能特点描述图:
2 Spring Cloud Config简介
Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。
Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,您可以为所有环境中的应用程序管理其外部属性。它非常适合spring应用,也可以使用在其他语言的应用上。随着应用程序通过从开发到测试和生产的部署流程,您可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。
Spring Cloud Config服务端特性:
- HTTP,为外部配置提供基于资源的API(键值对,或者等价的YAML内容)
- 属性值的加密和解密(对称加密和非对称加密)
- 通过使用@EnableConfigServer在Spring boot应用中非常简单的嵌入。
Config客户端的特性(特指Spring应用) - 绑定Config服务端,并使用远程的属性源初始化Spring环境。
- 属性值的加密和解密(对称加密和非对称加密)
3 Spring Cloud Config入门
3.1 准备工作
Config Server是一个可横向扩展、集中式的配置服务器,它用于集中管理应用程序各个环境下的配置,默认使用Git存储配置文件内容,也可以使用SVN存储,或者是本地文件存储。这里使用git作为学习的环境
(1)浏览器打开gitee.com,注册用户 ,注册后登陆码云管理控制台
(2)创建项目config-repository
(3)上传配置文件,将product_service工程的application.yml改名为product-dev.yml后上传
文件命名规则:
- {application}-{profile}.yml
- {application}-{profile}.properties
- application为应用名称 profile指的开发环境(用于区分开发环境,测试环境、生产环境等)
3.2 搭建服务端程序
加粗样式(1) 创建工程config_server,并引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
(2) 配置启动类
@EnableConfigServer //开启配置中心服务端功能
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class,args);
}
}
(3) 配置application.yml
server:
port: 10000 #服务端口
spring:
application:
name: config-server #指定服务名
cloud:
config:
server:
git:
uri: https://gitee.com/wenruox/config-repostory.git
- 通过 spring.cloud.config.server.git.uri : 配置git服务地址
- 通过`spring.cloud.config.server.git.username: 配置git用户名
- 通过`spring.cloud.config.server.git.password: 配置git密码
(4) 测试
启动此微服务,可以在浏览器上,通过server端访问到git服务器上的文件
3.3 修改客户端程序
(1) 引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
(2) 删除application.yml
springboot的应用配置文件,需要通过Config-server获取,这里不再需要。
(3) 添加bootstrap.yml
使用加载级别更高的 bootstrap.yml 文件进行配置。启动应用时会检查此配置文件,在此文件中指定配置中心的服务地址。会自动的拉取所有应用配置并启用
spring:
cloud:
config:
name: product # 应用名称 ,需要对应 git 中 配置文件名称的前半部分
profile: dev #开发环境
label: master # git中的分支
uri: http://127.0.0.1:10000 # config-server的请求地址
3.4 手动刷新
我们已经在客户端取到了配置中心的值,但当我们修改GitHub上面的值时,服务端(Config Server)能实时获取最新的值,但客户端(Config Client)读的是缓存,无法实时获取最新值。SpringCloud已经为我们解决了这个问题,那就是客户端使用post去触发refresh,获取最新数据,需要依赖springboot-starter-actuator
(1)引入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
(2)对应的controller类加上 @RefreshScope注解
@RestController
@RequestMapping("/product")
@RefreshScope
public class ProductController {
@Autowired
private ProductService productService;
@Value("${name}")
private String name;
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable Long id) {
return productService.findById(id);
}
@RequestMapping(value = "/test")
public String test() {
return name;
}
}
(3)修改配置文件
spring:
cloud:
config:
name: product # 应用名称 ,需要对应 git 中 配置文件名称的前半部分
profile: dev #开发环境
label: master # git中的分支
uri: http://127.0.0.1:10000 # config-server的请求地址
#开启动态刷新请求路径端点
management:
endpoints:
web:
exposure:
include: refresh
在postman中访问http://localhost:9002/actuator/refresh,使用post提交,查看数据已经发生了变化
4 配置中心的高可用
在之前的代码中,客户端都是直接调用配置中心的server端来获取配置文件信息。这样就存在了一个问题,客户端和服务端的耦合性太高,如果server端要做集群,客户端只能通过原始的方式来路由,server端改变IP地址的时候,客户端也需要修改配置,不符合springcloud服务治理的理念。springcloud提供了这样的解决方案,我们只需要将server端当做一个服务注册到eureka中,client端去eureka中去获取配置中心server端的服务既可。
4.1 服务端改造
(1) 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
(2) 配置文件,添加eureka 配置信息
# eureka 配置信息
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9000/eureka/ # 配置eureka server 路径
instance:
prefer-ip-address: true #开启ip注册
instance-id: ${spring.cloud.client.ip-address}:${server.port}
这样server端的改造就完成了。先启动eureka注册中心,在启动server端,在浏览器中访问:http://localhost:9000/ 就会看到server端已经注册了到注册中心了。
4.2 客户端改造
(1) 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
(2)修改 配置文件,添加eureka 配置信息
spring:
cloud:
config:
name: product # 应用名称 ,需要对应 git 中 配置文件名称的前半部分
profile: dev #开发环境
label: master # git中的分支
# uri: http://127.0.0.1:10000 # config-server的请求地址
# 通过注册中心获取config-server配置
discovery:
enabled: true # 开启服务发现
service-id: config-server
#开启动态刷新请求路径端点
management:
endpoints:
web:
exposure:
include: refresh
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9000/eureka/ # 配置eureka server 路径
instance:
prefer-ip-address: true #开启ip注册
instance-id: ${spring.cloud.client.ip-address}:${server.port}
(3)测试,通过启动两个不同端口的服务端来模拟集群环境,当一个服务端挂掉时,另一个服务端依然可以获取配置信息