zoukankan      html  css  js  c++  java
  • spring cloud深入学习(十)-----配置中心和消息总线(配置中心终结版)

    如果需要客户端获取到最新的配置信息需要执行refresh,我们可以利用webhook的机制每次提交代码发送请求来刷新客户端,当客户端越来越多的时候,需要每个客户端都执行一遍,这种方案就不太适合了。使用Spring Cloud Bus可以完美解决这一问题。

    Spring Cloud Bus

    Spring cloud bus通过轻量消息代理连接各个分布的节点。这会用在广播状态的变化(例如配置变化)或者其他的消息指令。Spring bus的一个核心思想是通过分布式的启动器对spring boot应用进行扩展,也可以用来建立一个多个应用之间的通信频道。目前唯一实现的方式是用AMQP消息代理作为通道,同样特性的设置(有些取决于通道的设置)在更多通道的文档中。

    Spring cloud bus被国内很多都翻译为消息总线,也挺形象的。大家可以将它理解为管理和传播所有分布式项目中的消息既可,其实本质是利用了MQ的广播机制在分布式的系统中传播消息,目前常用的有Kafka和RabbitMQ。利用bus的机制可以做很多的事情,其中配置中心客户端刷新就是典型的应用场景之一,我们用一张图来描述bus在配置中心使用的机制。

    根据此图我们可以看出利用Spring Cloud Bus做配置更新的步骤:

    • 1、提交代码触发post给客户端A发送bus/refresh
    • 2、客户端A接收到请求从Server端更新配置并且发送给Spring Cloud Bus
    • 3、Spring Cloud bus接到消息并通知给其它客户端
    • 4、其它客户端接收到通知,请求Server端获取最新配置
    • 5、全部客户端均获取到最新的配置

    项目示例

    客户端spring-cloud-config-client改造

    1、添加依赖

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

    需要多引入spring-cloud-starter-bus-amqp包,增加对消息总线的支持

    2、配置文件

    application.properties文件:

    ## 刷新时,关闭安全验证
    management.security.enabled=false
    ## 开启消息跟踪
    spring.cloud.bus.trace.enabled=true
    
    spring.rabbitmq.host=192.168.9.89
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=admin
    spring.rabbitmq.password=123456

    配置文件需要增加RebbitMq的相关配置,这样客户端代码就改造完成了。

    3、测试

    依次启动spring-cloud-eureka、spring-cloud-config-server、spring-cloud-config-client项目,在启动spring-cloud-config-client项目的时候我们会发现启动日志会输出这样的一条记录。

    2017-05-26 17:05:38.568  INFO 21924 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/bus/refresh],methods=[POST]}" onto public void org.springframework.cloud.bus.endpoint.RefreshBusEndpoint.refresh(java.lang.String)

    说明客户端已经具备了消息总线通知的能力了,为了更好的模拟消息总线的效果,我们更改客户端spring-cloud-config-client项目的端口为8003、8004依次启动,这样测试环境就准备好了。启动后eureka后台效果图如下:

    我们先分别测试一下服务端和客户端是否正确运行,访问:http://localhost:8001/neo-config/dev,返回信息:

    {
        "name": "neo-config", 
        "profiles": [
            "dev"
        ], 
        "label": null, 
        "version": null, 
        "state": null, 
        "propertySources": [
            {
                "name": "https://github.com/ityouknow/spring-cloud-starter/config-repo/neo-config-dev.properties", 
                "source": {
                    "neo.hello": "hello im dev"
                }
            }
        ]
    }

    说明server端都正常读取到了配置信息。

    依次访问:http://localhost:8002/hellohttp://localhost:8003/hellohttp://localhost:8004/hello,返回:hello im dev。说明客户端都已经读取到了server端的内容。

    现在我们更新neo-config-dev.properties 中neo.hello的值为hello im dev update并提交到代码库中,访问:http://localhost:8002/hello 依然返回hello im dev。我们对端口为8002的客户端发送一个/bus/refresh的post请求。在win下使用下面命令来模拟webhook.

    curl -X POST http://localhost:8002/bus/refresh

    执行完成后,依次访问:http://localhost:8002/hellohttp://localhost:8003/hellohttp://localhost:8004/hello,返回:hello im dev update。说明三个客户端均已经拿到了最新配置文件的信息,这样我们就实现了图一中的示例。

    改进版本

    在上面的流程中,我们已经到达了利用消息总线触发一个客户端bus/refresh,而刷新所有客户端的配置的目的。但这种方式并不优雅。原因如下:

    • 打破了微服务的职责单一性。微服务本身是业务模块,它本不应该承担配置刷新的职责。
    • 破坏了微服务各节点的对等性。
    • 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就不得不修改WebHook的配置。

    因此我们将上面的架构模式稍微改变一下

    这时Spring Cloud Bus做配置更新步骤如下:

    • 1、提交代码触发post请求给bus/refresh
    • 2、server端接收到请求并发送给Spring Cloud Bus
    • 3、Spring Cloud bus接到消息并通知给其它客户端
    • 4、其它客户端接收到通知,请求Server端获取最新配置
    • 5、全部客户端均获取到最新的配置

    这样的话我们在server端的代码做一些改动,来支持bus/refresh

    1、添加依赖

    <dependencies>
        <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>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

    需要多引入spring-cloud-starter-bus-amqp包,增加对消息总线的支持

    2、配置文件

    server:
      port: 8001
    spring:
      application:
        name: spring-cloud-config-server
      cloud:
        config:
          server:
            git:
              uri: https://github.com/ityouknow/spring-cloud-starter/     # 配置git仓库的地址
              search-paths: config-repo                             # git仓库地址下的相对地址,可以配置多个,用,分割。
              username: username                                        # git仓库的账号
              password: password                                    # git仓库的密码
      rabbitmq:
        host: 192.168.0.6
        port: 5672
        username: admin
        password: 123456
    
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8000/eureka/   ## 注册中心eurka地址
    
    
    management:
      security:
         enabled: false

    配置文件增加RebbitMq的相关配置,关闭安全验证。这样server端代码就改造完成了。

    3、测试

    依次启动spring-cloud-eureka、spring-cloud-config-server、spring-cloud-config-client项目,改动spring-cloud-config-client项目端口为8003、8004依次启动。测试环境准备完成。

    按照上面的测试方式,访问server端和三个客户端测试均可以正确返回信息。同样修改neo-config-dev.properties 中neo.hello的值为hello im dev update并提交到代码库中。在win下使用下面命令来模拟webhook触发server端bus/refresh.

    curl -X POST http://localhost:8001/actuator/bus-refresh

    执行完成后,依次访问:http://localhost:8002/hellohttp://localhost:8003/hellohttp://localhost:8004/hello,返回:hello im dev update。说明三个客户端均已经拿到了最新配置文件的信息,这样我们就实现了上图中的示例。

  • 相关阅读:
    Linux下分析某个进程CPU占用率高的原因
    Linux下查看某一进程所占用内存的方法
    jbd2导致系统IO使用率高问题
    Linux iotop命令详解
    1.Redis详解(一)------ redis的简介与安装
    Redis详解(十三)------ Redis布隆过滤器
    12.Redis详解(十二)------ 缓存穿透、缓存击穿、缓存雪崩
    面试问题总结
    算法与数据结构基础<二>----排序基础之插入排序法
    CarSim、Adams、Cruise和Simulink四款仿真软件的对比
  • 原文地址:https://www.cnblogs.com/alimayun/p/10994803.html
Copyright © 2011-2022 走看看