统一配置中心
我们之前做单体应用的时候是直接把配置写在application.yml中,但是如果是采用微服务架构的模式进行开发,这样的方式会存在哪些问题呢?首先维护困难、安全因素、更新配置时项目需要重启等等。针对这些问题,本文主要讲述的就是Spring cloud config这个组件,使用该组件可以很好的处理如下问题。
原始做法的缺陷
1、维护困难:假如一个服务,由多人开发,其中A在开发的时候,修改了配置,B再来开发的时候,需要测试别的一些功能,这个时候配置文件已经被A修改得面目全非了,这就造成了冲突。
2、安全因素:而且处于安全因素考虑,公司项目线上的配置基本是不对开发公开的,特别是数据库的账号密码这种,基本是只有运维才知道,把配置放在项目里面的话,每个开发人员都能看到,这种情况就需要对配置文件进行隔离。
3、更新配置需要重启:线上更新配置是经常发生的事情,比如更新一点小小的配置,难道都需要重启吗?使用spring cloud config就可以解决这一点。
统一配置中心的架构
配置中心到时候也会作为一个服务,这些配置为了方便管理,我们都把它放到git上,使用git控制起来会比较方便。如下图所示,其中箭头代表数据流动的方向:
最开始是把配置放在远端的Git,如Gitlab,Github或者自己搭建的私服,config-server把配置从远端Git拉下来之后,放到本地Git。config-server与本地Git之间是双向流动的,既会把远端的Git放到本地中,假如远端Git不能访问了,也会从本地Git把配置拉出来,拿到配置之后,就可以给微服务模块来使用。shop和order这两个服务,需要集成config-client这个组件。这就是统一配置中心整体的架构。
Config Server端使用流程
1、引入相关依赖
因为Config配置中心也是作为一个Client服务注册到Eureka Server的,所以必须引入Eureka Client的依赖,作为一个Eureka Client注册到Eureka Server上面。作为统一配置中心,必不可少的引入SpringCloud Config组件的依赖:
1<dependencies>
2 <dependency>
3 <groupId>org.springframework.cloud</groupId>
4 <artifactId>spring-cloud-config-server</artifactId>
5 </dependency>
6 <dependency>
7 <groupId>org.springframework.cloud</groupId>
8 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
9 </dependency>
10</dependencies>
2、启动类加注解
在启动类上添加注解支持@EnableConfigServer,其实不难发现很多SpringCloud组件的使用方式是一致的,都是先引入依赖,然后添加启动类的注解等流程,在这里不但需要@EnableConfigServer这个注解,同时不要忘记这也是一个Eureka Client,所以Eureka Client的注解和配置也是必不可少的。
1@SpringBootApplication
2@EnableDiscoveryClient
3@EnableConfigServer
4public class ConfigApplication {
5 public static void main(String[] args) {
6 SpringApplication.run(ConfigApplication.class, args);
7 }
8}
application.yml 配置文件:
1spring:
2 application:
3 name: config
4 cloud:
5 config:
6 server:
7 git:
8 uri: https://gitee.com/zouchanglin/config-repo
9 username: zouchanglin
10 password: 00101101010
11 # 指定配置文件存放的目录
12 basedir: /root/config
13eureka:
14 instance:
15 appname: config
16 client:
17 service-url:
18 defaultZone: http://localhost:8761/eureka
3、配置文件放入仓库
不难发现,我们在上面的配置文件中配置了Git的仓库地址、用户名以及密码,因为从架构图可以看出,其他服务组件配置文件需要放在一个Git仓库中,可以是Github、GitlabGit、Gitee或者是自己搭建的Git私服。我演示的时候直接放在了Gitee(码云)上面:
4、尝试访问配置文件
接下来可以尝试访问一下是否生效,开始Eureka Server,然后启动统一配置中心注册到Eureka Server上面。
可以看到,虽然我们只是在Master分支上提交一个order.yml,但是我们访问order.yml却无法访问,访问order-a.yml、order-b.yml、order-a.properties、order-b.properties、order-a.json、order-b.json却没有问题,也就是说SpringCloudConfig帮我们做了转换,那么具体的转换规则是什么呢?在日志里可以看到/{label}/{name}-{profiles}.yml
的字样,这些分别代表的意义如下:
- label:Git的分支,如master、dev、test、pre-release等等
- name:服务名称,在这里订单服务则为 order
- profiles:环境,比如测试环境、预上线环境、线上环境等
Config Client端使用流程
1、引入Config Client依赖
1<dependency>
2 <groupId>org.springframework.cloud</groupId>
3 <artifactId>spring-cloud-config-client</artifactId>
4</dependency>
2、修改配置文件
将application.yml修改为bootstrap.yml,意思就是从指定的配置中心来获取配置文件,然后再执行启动SpringBoot的核心流程:
1spring:
2 application:
3 name: shop
4 cloud:
5 config:
6 discovery:
7 enabled: true
8 service-id: CONFIG
9 profile: test
修改为bootstrap.yml后,也从原来的图表变成了一朵云,意思就是从服务器(统一注册中心)获取了
3、验证是否成功
在仓库中放置了 shop-test.yml 文件:
1server:
2 port: 8090
3
4eureka:
5 client:
6 service-url:
7 defaultZone: http://localhost:8761/eureka/
8
9spring:
10 application:
11 name: shop
12
13env: test
还在仓库中放置了 shop-dev.yml 文件
1server:
2 port: 8090
3
4eureka:
5 client:
6 service-url:
7 defaultZone: http://localhost:8761/eureka/
8
9spring:
10 application:
11 name: shop
12
13env: dev
两个配置文件的env属性不同,写一个Controller测试一下从统一配置中心拿到的配置文件的内容:
1@RestController
2@RequestMapping("/env")
3public class EnvController {
4
5 @Value("${env}")
6 private String env;
7
8 @GetMapping("print")
9 public String printEnv(){
10 return env;
11 }
12}
当我们把bootstrap.yml中的profile属性设置为dev的时候,拿到的配置文件就是shop-dev.yml,此时访问打印环境属性的接口打印出来就是dev;当我们把bootstrap.yml中的profile属性设置为test的时候,拿到的配置文件就是shop-test.yml,此时访问打印环境属性的接口打印出来就是test:
统一配置中心的高可用
在配置Eureka的高可用时,采用了相互注册的方式来实现高可用性。统一配置中心服务的高可用其实很简单,因为统一配置中心也Eureka的客户端,所以只要拥有足够的统一配置中心实例向Eureka Server注册即可实现高可用。由于是在本地开发环境,所以通过指定不同的端口号的方式来启动三个统一配置中心的实例:
在Eureka Server的界面可以看到,三个配置中心的实例已经注册到了Eureka Server上面:
使用配置中心的注意点
http://localhost:8761/eureka/
这个地址是默认的地址,假设我们改成其他的端口或者其他的IP地址就会报错找不到Eureka,其实要理解这一点并不难,因为要拿到配置文件的前提是得先找到统一配置中心的实例,统一配置中心的实例的前提是你得去Eureka Server上面找,前提是自身得注册到Eureka Server,但是此时并没有配置Eureka Server的注册地址,所以相当于与世隔绝是一个孤立的模块,自然会发生启动失败,所以关于Eureka Server的配置,无需由统一配置中心来分发,而是直接写在配置文件里即可。
当然还有一种方式,那就是指定统一配置中心的URL,这样就能直接找到统一配置中心的实例,在bootstrap.yml中:
1spring:
2 application:
3 name: shop
4 cloud:
5 config:
6 discovery:
7 enabled: true
8 service-id: CONFIG
9 profile: dev
10 uri: http://localhost:8888
总结一下就是:
- 方式一:先找到统一配置中心,获取配置,从配置中心给的配置中找到Eureka Server,再注册到Eureka Server
- 方式二:先找到Eureka Server,从Eureka Server找配置中心,从而获取对应的配置(推荐做法)
另外还有一点需要注意,那就是如果你需要的配置文件是shop-dev.yml,Git仓库同时存在shop.yml与shop-dev.yml,那么统一配置中心在拉取配置文件的时候,会把shop.yml和shop-dev.yml两个文件同时拉取下来,并且进行内容合并,所以我们通常遵循如下原则,那就是公共的配置内容写在shop.yml(对于本例而言)中,不同环境的配置内容写在shop-dev.yml或者shop-test.yml中。