一、概念部分
在分布式系统中,分散着许多不同的服务项目,这些服务项目共同为用户提供各种不同的服务。每个项目都有各自的配置文件,随着项目的增多,需要配置的文件也随着项目增多。
某一个项目配置的变动都有可能导致依赖这个项目的一系列其他项目需要重启和更新。
这样使得分布式项目配置变得格外麻烦,所以这时候就需要一个配置中心来统一管理这些配置。
如果把分布式系统中的各种服务当做我门的武器,那么配置中心就是存放这些十八般武器的弹药库,我们还可以为配置中心的配置文件添加git托管,开发人员只需要修改配置文件然后提交到git中心,分布式系统中的配置中心就会更新配置并刷新所有读取这些配置的微服务。
修改项目配置的整个过程就是 git push, 然后配置中心会自动替你刷新,不需要重启任何服务。
二、代码示例
1.创建项目 config-dashboard
添加build.gradle依赖
dependencies { compile('org.springframework.cloud:spring-cloud-config-server') testCompile('org.springframework.boot:spring-boot-starter-test') }
2.创建配置文件 application.yml
#spring配置spring: #应用配置 application: #应用名称(配置中心) name: spring-cloud-config-server #云服务配置 cloud: config: server: #git中心配置(这里我将配置文件存储在码云上) git: #配置文件所在的服务地址 uri: https://gitee.com/lanshiqin/spring-cloud #配置文件所在的文件路径 search-paths: service-registry-config #公开的项目不需要设置用户名和密码 username: password:#服务器配置server: #端口 port: 9010#服务器发现注册配置eureka: client: serviceUrl: #配置服务中心(可配置多个,用逗号隔开) defaultZone: http://localhost:9001/eureka
3.启动类添加注解
/** * 配置中心 * @ EnableConfigServer 启用配置服务 * @ EnableDiscoveryClient 启用发现客户端服务 */@SpringBootApplication@EnableConfigServer@EnableDiscoveryClientpublic class ConfigDashboardApplication { public static void main(String[] args) { SpringApplication.run(ConfigDashboardApplication.class, args); } }
由于在配置文件中配了配置文件所在的uri位置,这里我使用oschina的git托管,配置文件中还配置了配置文件所在位置的具体文件夹,所以需要新建如下图所示的 service-registry-config文件夹。
文件夹内可以存放我们的各个项目的配置文件,这里我新建了三个配置文件
每个配置文件中可以写我们需要的配置,这里我以service-registry-dev.yml文件为例,
配置文件内容如下图所示
4.启动项目,打开浏览器访问 http://localhost:9010/service-registry-config/dev
发现浏览器输出了如上图所示的json格式数据,证明我们读取oschina的配置文件成功。
为了后续客户端测试方便,我把配置中心部署到我自己的服务器上
配置中心集群实现高可用
我们可以在多台机器上运行配置中心实例,并且都注册到服务注册中心。
如果要在单台计算机上运行多个实例,则需要为项目新建多个配置文件,
每个配置文件中指定项目占用不同的端口。
为配置中心 config-dashboard项目新建3个配置文件
application-pro1.yml
#spring配置spring: #应用配置 application: #应用名称(配置中心) name: spring-cloud-config-server #云服务配置 cloud: config: server: #git中心配置(这里我将配置文件存储在码云上) git: #配置文件所在的服务地址 uri: https://gitee.com/lanshiqin/spring-cloud #配置文件所在的文件路径 search-paths: service-registry-config #公开的项目不需要设置用户名和密码 username: password:#服务器配置server: #端口 port: 9011#服务器发现注册配置eureka: client: serviceUrl: #配置服务中心(可配置多个,用逗号隔开) defaultZone: http://localhost:9001/eureka
application-pro2.yml
#spring配置spring: #应用配置 application: #应用名称(配置中心) name: spring-cloud-config-server #云服务配置 cloud: config: server: #git中心配置(这里我将配置文件存储在码云上) git: #配置文件所在的服务地址 uri: https://gitee.com/lanshiqin/spring-cloud #配置文件所在的文件路径 search-paths: service-registry-config #公开的项目不需要设置用户名和密码 username: password:#服务器配置server: #端口 port: 9012#服务器发现注册配置eureka: client: serviceUrl: #配置服务中心(可配置多个,用逗号隔开) defaultZone: http://localhost:9001/eureka
application-pro3.yml
#spring配置spring: #应用配置 application: #应用名称(配置中心) name: spring-cloud-config-server #云服务配置 cloud: config: server: #git中心配置(这里我将配置文件存储在码云上) git: #配置文件所在的服务地址 uri: https://gitee.com/lanshiqin/spring-cloud #配置文件所在的文件路径 search-paths: service-registry-config #公开的项目不需要设置用户名和密码 username: password:#服务器配置server: #端口 port: 9013#服务器发现注册配置eureka: client: serviceUrl: #配置服务中心(可配置多个,用逗号隔开) defaultZone: http://localhost:9001/eureka
打包
gradle build
上传到服务器,并运行
java -jar config-dashboard-0.0.1-SNAPSHOT.jar & java -jar config-dashboard-0.0.1-SNAPSHOT.jar --spring.profiles.active=pro1 & java -jar config-dashboard-0.0.1-SNAPSHOT.jar --spring.profiles.active=pro2 & java -jar config-dashboard-0.0.1-SNAPSHOT.jar --spring.profiles.active=pro3 &
访问服务注册中心集群 https://www.apiboot.cn/
可以看到服务注册中心里已经注册了 4个配置中心,配置中心已经实现了高可用。
有了配置中心后,我们还需要客户端来加载配置中心的配置文件数据。
这里我使用了osChina的git托管,当然你也可以使用GitHub来管理配置文件,我们每次修改配置文件,并且执行 git commit 和 git push 后,客户端如何实现自动刷新呢?
接下来我们来逐一实现
1.打开之前的项目 服务提供者 producer-service
编辑build.gradle 依赖如下
dependencies { compile('org.springframework.cloud:spring-cloud-starter-eureka') compile('org.springframework.cloud:spring-cloud-starter-config') compile('org.springframework.boot:spring-boot-starter-actuator') compile('org.springframework.boot:spring-boot-starter-web') testCompile('org.springframework.boot:spring-boot-starter-test') }
2.新建bootstrap.yml
#spring配置spring: #云配置 cloud: config: #配置文件前缀 (这里配置的name+profile为我们要读的配置文件 即 service-registry-dev) name: service-registry profile: dev #发现配置 discovery: #启用服务发现 enabled: true #指定server端(配置中心)的 spring.application.name的值,通过该值去注册中心取到配置中心的地址 service-id: spring-cloud-config-server#服务器发现注册配置eureka: client: serviceUrl: #配置服务中心(可配置多个,用逗号隔开) defaultZone: http://localhost:9001/eureka
SpringBoot在启动的时候加载application.yml前会先加载bootstrap.yml,我们需要把读取配置中心的设置写在这里。
3.新建控制器类 InfoController.java
/** * 读取配置中心的配置测试控制器 * @ RefreshScope 注解会在配置中心配置改变的时候 手动访问本项目的/refresh路径,就会实现自动刷新配置文件,重新加载配置文件中的数据 */@RestController@RefreshScopepublic class InfoController { @Value("${app.info}") private String info; // 注入app.info的值(本地配置文件没有这个配置,该配置从配置中心读取) /** * 输出 变量值 * @return 变量值 */ @RequestMapping("/appInfo") public String info(){ return info; } }
3.运行项目。为了测试方便,并实现稍后的自动刷新配置,我把客户端项目部署到我的服务器上,顺便用一个域名来绑定(域名不是必须的,可以通过ip)
项目部署到服务器上并允许后 访问地址:https://producer.apiboot.cn/appInfo
发现客户端成功的读取输出了我们在git oschina上的配置文件中的配置。
4.使用WebHooks实现提交代码时自动触发客户端的 /refresh
无论是osChina还是Github,都提供了WebHooks功能,可以实现Push提交的时候去触发一个post请求,该请求我们就写客户端项目的/refresh路径即可。
5.修改配置文件并提交
我在dev配置文件中添加了 “蓝士钦”,然后提交
此时我们再次访问客户端项目:https://producer.apiboot.cn/appInfo
发现我们的客户端已经自动从配置中心读取到了修改后的配置,而且不需要重启项目!
开发人员可以在任何地方通过git提交修改配置文件,即可实现自动更新分布式系统中各个服务的配置。
作者:蓝士钦
链接:https://www.jianshu.com/p/768b57968607