为了账号安全,请及时绑定邮箱和手机立即绑定

Spring Cloud Config结合Bus实现分布式配置中心

标签:
Java

概述


假设现在有个需求:

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

然后使用

http://localhost:8040/demo/dev

如果能输出

{“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接口

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】就可以了。


与携程的阿波罗对比


请参看:apollo相比于spring-cloud-config有什么优势

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

原文出处

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消