Spring Cloud学习系列第七篇【消息总线】

  上篇学习了搭建“分布式配置中心”,发现Spring Cloud Config这个配置中心动态刷新设计有点土,当配置仓库属性有更新动作的时候,需要对对应实例请求/refresh端点,该实例才能获取到更新的值,即使/refresh请求通过Git的hook钩子去自动触发,也需要维护一份各个实例的清单,对运维同学来说相对的不友好。这篇随笔我们先来结合Spring Cloud Bus进一步优化属性更新的例子,最后在总结下自身对Spring Cloud Bus理解。

  Spring Cloud Bus是在Spring Cloud中实现消息总线的一个组件,消息总线在微服务位置,可以做这样一个不太严谨的比喻:如果把各个微服务实例看成是一栋大厦的保安的话,那消息总线可以理解为每个保安手上的对讲机,每个保安队通过对讲机的讲话,所有保安都可以收到,并且选择是否要应答。Spring Cloud Bus实现消息总线需要配合消息中间件,目前主流的消息中间件有很多,但是Spring Cloud Bus仅支持RabbitMQ和KafKa,接下来的例子我以KafKa为例讲解。

一、Kafka安装

  在搭建Spring Cloud Bus之前,我们需要先安装好Kafka,并且启动。官网地址:http://kafka.apache.org/downloads.html,我下载的版本是kafka_2.10-0.10.0.1,下载好之后解压,就可以启动。

      

  先启动Zookeeper 

./bin/zookeeper-server-start.sh config/zookeeper.properties

   再启动Kafka

./bin/kafka-server-start.sh config/server.properties

二、 ConfigClient

  我们需要对上篇随笔的ConfigClient做些改造,使其能连接上Spring Cloud Bus实现的消息总线。在原有的pom.xml增加如下依赖。由于我们Kafka采用默认配置,因此我们这不需要增加额外的配置就能连接上消息总线了。

    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-bus-kafka</artifactId>
    </dependency>

三、ConfigServer

  同理,ConfigServer也需要做改动用于连接上消息总线,改动和ConfigClient一样,需要增加依赖,另外为了简化demo,我把spring-boot-starter-security注释掉了。

        <!--增加安全保护-->
        <!--<dependency>-->
            <!--<groupId>org.springframework.boot</groupId>-->
            <!--<artifactId>spring-boot-starter-security</artifactId>-->
        <!--</dependency>-->

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-kafka</artifactId>
        </dependency>
扫描二维码关注公众号,回复: 2574930 查看本文章

四、验证

  仅仅简单几步我们就把消息总线整合到了分布式配置中心里面去了。启动ConfigClient和ConfigServer,试着访问ConfigClient提供的http://localhost:7004/config-client接口,得到结果为。

  我们试下修改下配置仓库。把属性prop.name改成pumpkin-dev.properties.aa。

  最理想的情况是,此时我们的ConfigClient实例的属性就能得到自动的更新,但实际不是的,我们还需要POST方式访问任意一个连接上消息总线实例的/bus/refresh端点,该端点会通过消息总线广播到所有消息总线的实例,从而实现属性更新。为了方便日后维护,所以在这个例子中我把ConfigServer也连接上了消息总线,这样我们可以直接访问ConfigServer的端点curl -d "" "http://127.0.0.1:7003/bus/refresh",即可动态更新所有微服务实例的属性了。

五、总结

  消息总线的概念其实在很多系统都会有相似的概念,例如我们计算机上的各种总线等等,我的理解就是作为一种消息传递的渠道。使用Spring Cloud Bus实现消息总线的原理其实就是我们观察者模式,又或者叫消息订阅模式可能更贴切点,在消息订阅模式中存在如下几种角色:事件、消息监听者、消息发布者。当我们需要对属性进行更新时,访问某一实例的/bus/refresh端点,该实例就是消息发布者,而更新属性者则为一个事件,消息发布者把事件发送到消息中间件中(Kafka或者RabbitMQ),由于所有的消息监听者和消息发布者都会订阅同一主题的消息,因此所有消息监听者都会从消息中间件中获取到这一事件,从而完成属性更新动作。

  在Spring Cloud Bus设计中,它是依赖Spring Cloud Stream与消息中间件进行通信的,它只关心自身业务逻辑,进而实现自身事件、消息监听者、消息发布者一整套消息总线流程,Spring Cloud Stream专门用于与消息中间件打交道的,而且提供了统一的接口给上层调用,于是Spring Cloud Bus就不需要关心底层的消息中间件到底只RabbitMQ还是Kafka了,只要提供对应的实现依赖即可实现自身消息定义,比如spring-cloud-starter-bus-kafka。如果我们需要把中间件换成RabbitMQ,只需要把spring-cloud-starter-bus-kafka改成spring-cloud-starter-bus-amqp即可,不需要改动任何代码,实际上正是因为Spring Cloud Stream目前支持RabbitMQ和Kafka,所以Spring Cloud Bus也就只支持这2个消息中间件了。

六、参考资料

Spring Cloud微服务实战-翟永超。本系列的学习都是参考该书籍学习的,同时源码使用的Spring Boot和Spring Cloud的版本也与该书保持一致。

七、源码

码云地址:[email protected]:pumpkingg/Spring-Cloud-Study.git 该篇随笔对应的代码是master分支下命名为blog6的Tag

猜你喜欢

转载自www.cnblogs.com/yipaihushuo/p/9428146.html