利用Spring Cloud Config结合Bus实现分布式配置中心的步骤

时间:2021-05-02

概述

假设现在有个需求:

我们的应用部署在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组件

? 1 2 3 4 5 6 7 8 <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>

【2】启动类使用@enableconfigserver注解

? 1 2 3 4 5 6 7 8 9 10 11 12 13 package spring.cloud.config; import org.springframework.boot.springapplication; import org.springframework.boot.autoconfigure.springbootapplication; import org.springframework.cloud.config.server.enableconfigserver; @enableconfigserver @springbootapplication public class configapplication { public static void main(string[] args) { springapplication.run(configapplication.class, args); } }

【3】application.yml文件配置rabbitmq和git仓库

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 server: port: 8040 spring: 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: guest management: security: enabled: false

配置rabbitmq是因为bus组件需要使用它来通知客户端,配置有变动。另外,记得使用

? 1 2 3 management: security: enabled: false

将验证关闭掉,不然后面的操作,老是报授权错误。

到此服务端配置中心已经搞定了。现在你就可以在服务端先做个小实验,提交一个demo-dev.properties文件,文件的内容如下:

? 1 address=hello

然后使用

http://localhost:8040/demo/dev

如果能输出

? 1 {“address”:”hello”}

就说明spring cloud config跟git的交互是ok的。

客户端接入配置中心

我们的目标:

当把配置信息修改完提交到git上后,所有接入到spring cloud config的客户端马上能收到通知,并且拿到最新的配置信息。
下面介绍如何实现这个目标。

客户端只需要做几个小步骤即可完成接入动作。

【1】引入依赖

? 1 2 3 4 5 6 7 8 9 10 11 12 13 <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>

引入spring-boot-starter-web只是为了做实验而已。

【2】配置rabbitmq和引入配置中心的url

application.properties

? 1 2 3 4 5 6 7 spring.application.name=spring-cloud-config-client1 server.port=8042 management.security.enabled=false spring.rabbitmq.host=127.0.0.1 spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest

bootstrap.properties

? 1 2 3 4 spring.cloud.config.name=demo spring.cloud.config.profile=dev spring.cloud.config.label=master spring.cloud.config.uri=http://localhost:8040/

有三个注意点:

1、关闭验证:management.security.enabled=false

2、spring cloud config相关的配置一定一定要放到bootstrap.properties里

3、使用spring.cloud.config.uri指定配置中心的地址

另外,对于客户端来说,启动类是不用加上任何跟config和bus有关的注解的

到此客户端搞定了,我们可以使用一个controller来开始做实验了。

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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 @refreshscope public class hellocontroller { @value("${address}") private string address; @requestmapping("/address") public string getaddress() { return this.address; } }

假设上面的hellocontroller需要用到address这个配置,只需要使用@refreshscope和@value注解就可以了

? 1 2 @refreshscope public class hellocontroller {} ? 1 2 @value("${address}") private string address;

为了验证客户端是否能拿到最新的配置信息,提供一个

? 1 2 3 4 @requestmapping("/address") public string getaddress() { return this.address; }

方法。

我们修改一下demo-dev.properties文件,将值改成

? 1 address=hello update

并提交到git上。这个时候我们调用getaddress接口

http://localhost:8041/address

发现并没有拿到最新的值。那是因为push到git的这个动作做完后,我们没有通知到spring cloud bus。可以使用postman来做一个post请求,调用如下接口,来通知bus。

http://localhost:8040/bus/refresh

这个接口一旦调用成功,bus会利用rabbitmq通知所有的客户端,配置已经更新。

特别注意:

我们是调用服务端的/bus/refresh接口,不是去调用客户端的/bus/refresh接口。

如果每次提交,都要去调用服务端的/bus/refresh接口,那这个也太麻烦了。可以使用webhook来帮一下忙。

如果你们用的是新的gitlab,那么只需要在工程里面,点击【settings】,再点击【integrations】,就可以设置webhook了,如下图:

url里面填入配置中心服务端的/bus/refresh接口地址,然后点击【添加webhook】就可以了。

与携程的阿波罗对比

spring cloud config的精妙之处在于它的配置存储于git,这就天然的把配置的修改、权限、版本等问题隔离在外。通过这个设计使得spring cloud config整体很简单,不过也带来了一些不便之处。

下面尝试做一个简单的小结:

功能点 apollo spring cloud config 备注 配置界面 一个界面管理不同环境、不同集群配置 无,需要通过git操作 配置生效时间 实时 重启生效,或手动refresh生效 spring cloud config需要通过git webhook,加上额外的消息队列才能支持实时生效 版本管理 界面上直接提供发布历史和回滚按钮 无,需要通过git操作 灰度发布 支持 不支持 授权、审核、审计 界面上直接支持,而且支持修改、发布权限分离 需要通过git仓库设置,且不支持修改、发布权限分离 实例配置监控 可以方便的看到当前哪些客户端在使用哪些配置 不支持 配置获取性能 快,通过数据库访问,还有缓存支持 较慢,需要从git clone repository,然后从文件系统读取 客户端支持 原生支持所有java和.net应用,提供api支持其它语言应用,同时也支持spring annotation获取配置 支持spring应用,提供annotation获取配置 apollo的适用范围更广一些

我个人还是推荐使用spring cloud config,很轻量级、且社区活跃,遇到问题很好找到解决方案。另外呢,我个人认为阿波罗和spring cloud config的区别就只是有木有界面而已。界面做得到的,我们通过git也可以的,只是用户体验没那么好而已。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:https://blog.csdn.net/linsongbin1/article/details/80194314

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章