如果需要客户端获取到最新的配置信息需要执行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。说明三个客户端均已经拿到了最新配置文件的信息,这样我们就实现了上图中的示例。

spring cloud深入学习(十)-----配置中心和消息总线(配置中心终结版)的更多相关文章

  1. Spring Cloud(九):配置中心(消息总线)【Finchley 版】

    Spring Cloud(九):配置中心(消息总线)[Finchley 版]  发表于 2018-04-19 |  更新于 2018-05-07 |  我们在 Spring Cloud(七):配置中心 ...

  2. spring cloud深入学习(十二)-----Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式

    Zuul的核心 Filter是Zuul的核心,用来实现对外服务的控制.Filter的生命周期有4个,分别是“PRE”.“ROUTING”.“POST”.“ERROR”,整个生命周期可以用下图来表示. ...

  3. spring cloud深入学习(九)-----配置中心服务化和高可用

    在前两篇的介绍中,客户端都是直接调用配置中心的server端来获取配置文件信息.这样就存在了一个问题,客户端和服务端的耦合性太高,如果server端要做集群,客户端只能通过原始的方式来路由,serve ...

  4. spring cloud(学习笔记)高可用注册中心(Eureka)的实现(二)

    绪论 前几天我用一种方式实现了spring cloud的高可用,达到两个注册中心,详情见spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一),今天我意外发现,注册中心可以无限 ...

  5. Spring Cloud Alibaba系列(二)nacos作为服务配置中心

    Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持.使用 Spring Cloud Alibaba Nacos Config,您可 ...

  6. 《Spring Cloud》学习(二) 负载均衡!

    第二章 负载均衡 负载均衡是对系统的高可用.网络压力的缓解和处理能力扩容的重要手段之一.Spring Cloud Ribbon是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于Netfli ...

  7. 《Spring Cloud》学习(一) 服务治理!

    前言:之前网上学习过Spring Cloud,对于工作上需要是足够了,总归对于一些方面一知半解,最近难得有些闲暇时间,有幸读了崔永超先生的<Spring Cloud 微服务实战>,一方面记 ...

  8. spring cloud深入学习(四)-----eureka源码解析、ribbon解析、声明式调用feign

    基本概念 1.Registe 一一服务注册当eureka Client向Eureka Server注册时,Eureka Client提供自身的元数据,比如IP地址.端口.运行状况指标的Uri.主页地址 ...

  9. SpringCloud学习系列之五-----配置中心(Config)和消息总线(Bus)完美使用版

    前言 在上篇中介绍了SpringCloud Config的使用,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的分布式配置中心( ...

随机推荐

  1. Hibernate之Inverse的用法

    在多的一端配置Inverse设置为true,来自动管理关系

  2. AutoLayout(自动布局)入门

    这是WWDC2012笔记系列中的一篇,完整的笔记列表可以参看这里.如果您是首次来到本站,也许您会有兴趣通过RSS的方式订阅本站. AutoLayout在去年的WWDC上被引入Cocoa,而在今年的WW ...

  3. arcmap分类标注问题

    在给图层标注的时候,经常出现冲突后有些标注出不来,需要将某些个别的点要素进行标注位置调整,如下图: 处理步骤如下, (1)打开Maplex标注引擎.从ToolBars中打开Labeling工具,勾选U ...

  4. day 70 Django基础五之django模型层(二)多表操作

    Django基础五之django模型层(二)多表操作   本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 ORM ...

  5. python 安装bs4

    1, 下载地址https://www.crummy.com/software/BeautifulSoup/#Download ------------------------------------- ...

  6. python3爬虫lxml模块的安装

    1:在下载lxml之前,要先查看python的版本信息, 在CMD命令行输入python 再输入import pip; print(pip.pep425tags.get_supported()) -- ...

  7. 深夜Python - 第2夜 - 爬行

    深夜Python - 第2夜 - 爬行 我曾经幻想自己是一只蜗牛,有自己的一只小壳,不怕风,不怕雨,浪荡江湖,游历四方……夜猫兄一如既往地打断了我不切实际的幻想:“浪荡?游历?等你退休了都爬不出家门口 ...

  8. [转]async & await 的前世今生(Updated)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...

  9. 六. Default arguments 参数默认值

    示例: 注意点:函数是会默认声明参数变量的,所以不需要再重新声明一次,否则会报错 错误示例如下: 函数参数的传值方法: 需要注意的是:如果要给第二个参数传值,那第一个参数要传undefined,而不能 ...

  10. 菜鸟nginx源码剖析数据结构篇(一)动态数组ngx_array_t[转]

    菜鸟nginx源码剖析数据结构篇(一)动态数组ngx_array_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn ...