Spring Cloud Config 顾名思义,它是一个与配置有关的框架。
Spring Cloud的每一个组件都有各自的配置,我们在开发阶段会不停的更新配置并启动,那么当我们将所有的服务打包,并发布到线上时,我们还得重新将所有的配置再做一次更新,因为线下生成环境和线上部署环境肯定存在大量的不同,比如把localhost改为具体的线上服务器ip地址,并且重新调整各个组件所用端口号。
但是大量的微服务以及各种组件中涉及到许多配置文件的修改,这里改一下那里改一下,这极有可能在发布时出现各种各样的问题,且作为某个模块的开发者可以看到自己模块的配置文件中的各种连接ip和用户名密码,这在大型项目中是非常危险的,实际开发时,这些配置信息应该只有项目经理一个人能掌握、修改
一般整个项目向外网暴露的ip地址只有Nginx(并且Nginx服务器的密码每隔一段时间就会更新一次且是无法记住的字符串,以此保证Nginx的安全),其他的注册中心、业务模块、redis等全都拒绝外网访问,只能通过内网实现部署,再通过Nginx跳转使用,要部署的业务模块等组件信息只能由项目经理完成
基于这样的需求,从业者提出了一个新的名词,我们称之为devops,所谓devops其实是“软件开发人员(Dev)”和“IT运维技术人员(Ops)”的组合,我们期望能够让开发者更加快速的与运维人员合作并保证发布的流程环境切换的便利性。至此,提出了自动化运维以及统一配置中心等概念,而Spring Cloud Config就是基于这样的情况下出来的分布式统一配置中心解决方案。
一个正常的微服务项目,有十几个模块,然后整个项目还分开发环境、应用环境、准应用环境等版本
假设有二十个模块,四个版本,这样整个项目的配置文件就有80个,因此必须有一个统一管理配置文件的地方——Spring Cloud Config就是基于这样的情况下出来的分布式统一配置中心解决方案
当我们建立统一配置中心之后,就可以从配置中心拉取所有的配置文件,整个架构会更加清晰明显,配置文件也会更方便维护
配置中心要连接一个版本控制工具,版本控制工具中保存着所有配置文件
假设现在版本控制工具在A服务器上,配置中心在B服务器上,现在业务模块请求配置中心,配置中心将会通过IO获取版本控制工具上的配置信息并保存在B服务器上,然后返回配置文件给业务模块,下次业务模块再请求时,配置中心会比对本地版本和版本控制工具里的版本,如果两者相同,那么配置中心就会直接返回本地版本的配置文件给业务模块,如果两者发生变化,才重新抓取配置文件
如图,是svn管理的文件版本,基于版本号比对配置文件是否发生变化,之所以版本号变更那么快,是因为每提交一次文件,版本号都会改变
全流程说明:
将所有的配置文件保存至版本管理工具
将配置中心的远程配置地址设置为版本控制工具的地址,配置中心会从版本控制工具中拉取对应的配置文件并保存至本地。
将配置中心注册到Eureka完成服务注册,配置中心注册到注册中心之后,即可完成配置中心的高可用。
将所有的微服务配置改为链接Eureka发现配置中心,拉取指定配置中心的版本的配置文件。
修改微服务的配置文件为启动预加载。
由于config本身提供高可用集群方案,而这个集群方案需要依赖Eureka Server,所以要独立设置一个springboot项目作为配置中心,并且在创建Config服务时,需要引入Eureka Client,同时引入Config连接SVN需要的依赖库。
使用springboot骨架创建一个独立的springboot项目并导入依赖,config单独写在这个工程里
在pom文件中导入版本控制工具的依赖,如果使用的是svn则如下图,如果使用的是别的版本控制工具,则根据实际情况导入
在项目的springboot启动类上使用注解@EnableConfigServer开启config服务端,并使用@EnableEurekaClient把配置中心注册到注册中心
属性详解:
- uri :svn地址
- username : svn账户
- password :svn密码
- basedir :下载的配置文件本地存放路径
- default-label :引用分支,默认为trunk。若需要使用其他的分支需要声明属性并指定值
spring.profiles.active = subversion 指定配置中心使用svn
eureka.client.service-url.defaultZone=要关联的注册中心url
注意:在新版springboot中,uri 不支持中文路径,但是在早期springboot版本中是支持的,这应该是新版本的bug,如果报错找不到文件,可以考虑修改为全英文路径或者切换springboot版本,推荐用全英文路径,能避免很多奇怪的问题
server: port: 7777 spring: application: name: config-server cloud: config: server: svn: basedir: D:\config username: 403201 password: 4032@javasm uri: svn://192.168.5.100/project/4032/student/config profiles: active: subversion eureka: client: service-url: defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka
将其他客户端的配置文件上传至版本控制工具,这里以svn举例
svn作为版本协同工具,拥有创建多个分支的功能,多个分支标记着多个版本环境,用于在线服务回滚。
url可作为config在yml配置文件中设置的uri连接地址
不同的文件夹区分不同的分支版本,可在config端连接时指定,默认是trunk目录
trunk目录用于存放开发版本的配置文件
release目录用于存放正式上线的配置文件
作为存放开发版本配置文件的trunk目录下,也要进一步对每一个配置文件区分三个版本,这三个版本有各自不同的作用域。
分别是userService.yml、userService-dev.yml(开发环境)、userService-pro.yml(生产环境),第一个属于公共配置文件,后面两个属于不同版本的差异化文件,只记录了差异化信息
注意下面给出的代码中,为了测试才将spring.application.name设置为不同,在真正开发的过程中,一定要将所有的相同的服务设置为相同的应用名
配置成功后,可以在注册中心看到配置中心
能通过访问注册中心给出的地址看到如下画面则表示成功
通过直接访问配置中心url+配置文件名,可以看到,无法访问不加后缀的配置文件
但是可以访问加了后缀的配置文件,并且可以看到整个yml文件除了原文件中的信息外,还多了源文件中没有的server以及eureka,这些多出来的信息,正是来自于userService.yml这个公共配置文件
除了访问yml格式,也能访问properties或者json,配置中心可以自动把配置文件转为这三种格式
配置中心会自动把配置文件保存到了指定的路径中(从模拟svn所在服务器的文件夹保存到了模拟配置中心所在服务器指定的文件夹)
当开发者修改了配置文件信息并使用svn提交后,配置中心会自动比对本地缓存的文件和用户提交的文件版本号,发现不一致时就会自动拉取新的配置文件,无需开发者手动更新配置文件,也无需重启整个项目
Config服务端高可用比较简单,只需要启动多台config服务实例即可完成集群高可用,分流操作由客户端去Eureka发现Config服务,并拉取配置时分配具体服务器。
在springcloud的父模块的pom文件中,在原有的Eureka依赖下,加入Spring Cloud Config相关依赖
在各个子模块(user、order)的yml配置文件中加入下面的代码
spring: application: name:userService cloud: config: enabled:true service-id:config profile:dev
属性详解:
spring.application.name : 应用名(注意,在连接了配置中心的情况下,这里指配置中心的文件名)
spring.cloud.config.discovery.enabled : 开启配置中心。(true为开启,false为不开启,默认为false)
spring.cloud.config.discovery.service-id :配置中心在Eureka注册中心的名称
spring.cloud.config.profile :指定要使用的配置文件的后缀
注意:
由spring.application.name+ spring.cloud.config.profile组成了当前客户端对应的配置文件的文件名(当前示例的结果为 :userService-dev)
如果应用名随便填写,仍然可以启动并注册,但是无法读取到正确的配置文件
SpringCloud所有的组件都是依赖SpringBoot进行二次封装的,默认的配置文件是application.properties,项目在启动时会按照启动类赋予的功能加载配置文件中的属性。
但是目前的配置文件是一个远程地址,只是放在svn中,需要先拉取到配置文件,再加载并启动springboot项目,所以配置文件需要在SpringBoot加载配置内容前就拿到具体配置,就需要设置预加载。
SpringBoot前置了预加载功能,只需要在resource目录下创建一个bootstrap.yml(或者.properties格式)的配置文件,这样项目在启动时就会预先加载bootstrap配置文件。
此时各个子模块中的配置文件得改名为bootstrap.yml(或者.properties格式)
系统级配置,最先执行
开发级配置,当系统初始化之后才会执行
SpringCloud项目中,在bootstrap的配置中开启配置中心即可,无需再像其他组件一样添加启动注解。
根据上面的步骤配置好客户端后,启动所有springboot项目,此时就可以看到控制台提示,已经从配置中心抓取了配置文件
只需要在各个子模块的配置文件中,把profile改一下就行了
实际开发时,个人开发环境下,把profile改为dev,然后就可以根据自己开发需要在bootstrap.yml中写各个配置
正式上线时把改profile改为pro,然后就不用管了,各种连接ip、账号密码都会自动切换为线上版本,而这些配置不需要开发人员操心,会有项目经理配置好