概述
假设现在有个需求:
我们的应用部署在10台机器上,当我们调整完某个配置参数时,无需重启机器,10台机器自动能获取到最新的配置。
如何来实现呢?有很多种,比如:
1、将配置放置到一个数据库里面
,应用每次读取配置都是直接从DB读取。这样的话,我们只需要做一个DB变更,把最新的配置信息更新到数据库即可。这样无论多少台应用,由于都从同一个DB获取配置信息,自然都能拿到最新的配置。
2、每台机器提供一个更新配置信息的updateConfig接口
,当需要修改配置时,挨个调用服务器的updateConfig
接口。
3、借助redis
来实现,把配置信息放置到redis上,但是这样子,就每次都得去redis读取,多了一些网络请求。
上面这三种方法是最容易想到的,也很容易做,但是缺点当然也非常的多。虽说缺点很多,但是某些传统企业还真是这么干的。
在互联网企业里,基本没见过这么玩的,都是会使用分布式配置中心。用开源的或者自己实现,目前开源的分布式配置中心有很多,而spring cloud config
就是其中的佼佼者。下面我们就用spring cloud config
来实现一个分布式配置中心。
是否使用最新的Spring Boot 2.0 版本
我曾经使用最新的spring cloud 2.0做了一个分布式是配置中心的demo。原本以为很简单,但是居然足足花了一天才搞定。有以下几个原因:
1、spring cloud对应的文档没有完全更新,出了问题,在文档里找不着;
2、目前使用2.0版本的公司很少,网上也没什么具体实战文章介绍。出了问题后,百度是找不到解决方案的。而google也基本很难找到方案,都是一些零星的知识碎片;
3、2.0这个版本,config和bus这块有些小变动,如果还按照1.5.x的版本来弄的话,是行不通的。
基于上面几个原因,建议使用1.5.x的版本靠谱些。下面这篇文章会以下面的版本来介绍的:
spring boot:
1.5.2.RELEASE
对应的spring cloud使用:
Dalston.RELEASE
搭建spring cloud config server
如果你只是想把配置统一由spring cloud config来管理,而暂时不想做配置中心的高可用的话,则只需要config和bus两个组件就够了。但是如果要保证高可用,还得使用spring cloud的注册发现组件。
除了config和bus之外,我们还需要使用git。因为spring cloud config是使用git来做版本管理的。
基于spring cloud config做一个配置中心,很简单,只要几个小步骤就搞定了。
【1】引入config和bus组件
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId></dependency>123456789
【2】启动类使用@EnableConfigServer注解
package spring.cloud.config;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.config.server.EnableConfigServer;@EnableConfigServer@SpringBootApplicationpublic class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class, args); } }1234567891011121314
【3】application.yml文件配置rabbitmq和git仓库
server: port: 8040spring: application: name: spring-cloud-config-server cloud: config: server: git: uri: https://gitlab.xxxxxx.com/config/xxxxxxx.git search-paths: username: xxxxx password: xxxxxx activemq: host: 127.0.0.1 port: 5672 username: guest password: guestmanagement: security: enabled: false123456789101112131415161718192021
配置RabbitMQ是因为bus组件需要使用它来通知
客户端,配置有变动。另外,记得使用
management: security: enabled: false123
将验证关闭掉,不然后面的操作,老是报授权错误。
到此服务端配置中心已经搞定了。现在你就可以在服务端先做个小实验,提交一个demo-dev.properties
文件,文件的内容如下:
address=hello1
然后使用
如果能输出
{“address”:”hello”}
就说明spring cloud config跟git的交互是ok的。
客户端接入配置中心
我们的目标:
当把配置信息修改完提交到git上后,所有接入到spring cloud config的客户端马上能收到通知,并且拿到最新的配置信息。
下面介绍如何实现这个目标。
客户端只需要做几个小步骤即可完成接入动作。
【1】引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>12345678910111213
引入spring-boot-starter-web
只是为了做实验而已。
【2】配置RabbitMQ和引入配置中心的url
application.properties
spring.application.name=spring-cloud-config-client1 server.port=8042management.security.enabled=false spring.rabbitmq.host=127.0.0.1spring.rabbitmq.port=5672spring.rabbitmq.username=guest spring.rabbitmq.password=guest123456789
bootstrap.properties
spring.cloud.config.name=demo spring.cloud.config.profile=dev spring.cloud.config.label=master spring.cloud.config.uri=http://localhost:8040/1234
有三个注意点:
1、关闭验证:management.security.enabled=false
2、spring cloud config相关的配置一定一定要放到bootstrap.properties里
3、使用spring.cloud.config.uri指定配置中心的地址
另外,对于客户端来说,启动类是不用加上任何跟config和bus有关的注解的
。
到此客户端搞定了,我们可以使用一个controller来开始做实验了。
package springcloudconfig.client;import org.springframework.beans.factory.annotation.Value;import org.springframework.cloud.context.config.annotation.RefreshScope;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RefreshScopepublic class HelloController { @Value("${address}") private String address; @RequestMapping("/address") public String getAddress() { return this.address; } }123456789101112131415161718
假设上面的HelloController
需要用到address这个配置,只需要使用@RefreshScope
和@value
注解就可以了
@RefreshScopepublic class HelloController {}12
@Value("${address}") private String address;12
为了验证客户端是否能拿到最新的配置信息,提供一个
@RequestMapping("/address") public String getAddress() { return this.address; }1234
方法。
我们修改一下demo-dev.properties
文件,将值改成
address=hello update1
并提交到git上。这个时候我们调用getAddress接口
发现并没有拿到最新的值。那是因为push到git的这个动作做完后,我们没有通知到spring cloud bus。可以使用postman来做一个post
请求,调用如下接口,来通知bus。
这个接口一旦调用成功,bus会利用RabbitMQ通知所有的客户端,配置已经更新。
特别注意:
我们是调用
服务端
的/bus/refresh
接口,不是去调用客户端的/bus/refresh
接口。
如果每次提交,都要去调用服务端的/bus/refresh
接口,那这个也太麻烦了。可以使用webhook来帮一下忙。
如果你们用的是新的gitlab,那么只需要在工程里面,点击【Settings】,再点击【Integrations】,就可以设置webhook了,如下图:
url里面填入配置中心服务端的/bus/refresh
接口地址,然后点击【添加Webhook】就可以了。
与携程的阿波罗对比
请参看:apollo相比于spring-cloud-config有什么优势
我个人还是推荐使用Spring Cloud Config,很轻量级、且社区活跃,遇到问题很好找到解决方案。另外呢,我个人认为阿波罗和Spring Cloud Config的区别就只是有木有界面而已。界面做得到的,我们通过git也可以的,只是用户体验没那么好而已。
共同学习,写下你的评论
评论加载中...
作者其他优质文章