Spring Cloud第十二篇 | 消息总线Bus
本文是Spring Cloud专栏的第十二篇文章,了解前十一篇文章内容有助于更好的理解本文:
一、前言
由于在没有使用消息总线的时候,我们如果需要修改某个配置,如果涉及修改的微服务节点比较多,我们需要手动的一个节点一个节点的刷新非常麻烦,在微服务架构的系统中,我们通常会使用轻量级的消息代理来构建一个共用的消息主题让系统中所有微服务实例都连接上来,由于该主题中产生的消息会被所有实例监听和消费,所以我们称它为消息总线。在总线上的各个实例都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息,例如配置信息的变更或者其他一些管理操作等。
由于消息总线在微服务架构系统中被广泛使用,所以它同配置中心一样,几乎是微服务架构中的必备组件。Spring Cloud作为微服务架构综合性的解决方案,对此自然也有自己的实现,通过使用Spring Cloud Bus可以非常容易地搭建起消息总线,同时实现了一些消息总线中的常用功能,比如配合Spring Cloud Config实现微服务应用配置信息的动态更新等,架构如图所示:
目前版本,Spring Cloud Bus仅支持两款中间件产品,RabbitMQ和Kafka,本案例使用RabbitMQ实现Spring Cloud Bus的应用
RabbitMQ安装步骤以及使用自行百度啦。。。
二、整合消息总线bus
1、修改以前的springcloud-config-server,springcloud-config-client块添加消息总线依赖,actuator依赖在前几篇案例中已经在父模块(springcloud-learn)中引入,此处不需要再次引入
<!--spring cloud bus 整合rabbitmq -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
2、rabbitmq服务地址:http://47.112.11.147:15672/ rabbitmq用户名为:admin密码为:123456
3、在springcloud-config-server模块基础上往application.yml添加bus和rabbitmq的相关配置以及暴露bus-refresh端点
spring:
cloud:
bus:
#控制bus消息总线是否能用
enabled: true
#打开bus追踪
trace:
enabled: true
rabbitmq:
addresses: 47.112.11.147
port: 5672
username: admin
password: 123456
virtual-host: /
management:
endpoints:
web:
exposure:
include: ["info","health","bus-refresh"]
4、在springcloud-config-client模块基础上往application.yml添加rabbitmq相关配置就行了
spring:
rabbitmq:
addresses: 47.112.11.147
port: 5672
username: admin
password: 123456
virtual-host: /
5、启动配置中心服务端(springcloud-config-server)查看bus相应的转换器Exchange以及Type对应的topic,并且同时在控制台上通过日志可以看到bus-refresh端点暴露出来了
RabbitMQ的Topic模式如图所示:
如果不懂RabbitMQ的话也不影响你的Bus使用
查看rabbitmq控制台看到bus相应对列创建了
查看绑定关系,springcloud bus相应对列已经绑定到了springcloud bus转换器上了
6、启动配置中心客户端(springcloud-config-client)可以看到该对列也绑定到spirngcloud bus转换器上了
7、我们在复制springcloud-config-client的配置,新建文件bootstrap-configclient8882.yml配置文件如下,创键启动类启动SpringcloudConfigClient8882Application
server:
port: 8882
spring:
application:
name: springcloud-config-client
cloud:
config:
#uri则表示配置中心的地址
#uri: http://localhost:8888
#注:config 客户端在没有 spring.cloud.config.name属性的时候,服务端{application} 获取的是客户端
#spring.application.name的值,否则,获取的是 spring.cloud.config.name的值。
#1)、当没有spring.cloud.config.name时,客户端获取的是spring.application.name 所对应的git库中的文件,并且只能
#获取一个文件,
#2)、当一个项目中有需求要获取多个文件时,就需要用到spring.cloud.config.name这个属性,以逗号分割
name: configclient
profile: dev
#label对应了label部分
label: master
# username: coding-farmer
# password: 123456
discovery:
#表示开启通过服务名来访问config-server
enabled: true
#则表示config-server的服务名
service-id: springcloud-config-server
#失败快速响应
fail-fast: true
retry:
#配置重试次数,默认为6
max-attempts: 6
#初始重试间隔时间,默认1000ms
initial-interval: 1000
#间隔乘数,默认1.1
multiplier: 1.1
#最大间隔时间,默认2000ms
max-interval: 2000
rabbitmq:
addresses: 47.112.11.147
port: 5672
username: admin
password: 123456
virtual-host: /
eureka:
client:
service-url:
defaultZone: http://localhost:8700/eureka
#客户端每隔30秒从Eureka服务上更新一次服务信息
registry-fetch-interval-seconds: 30
#需要将我的服务注册到eureka上
register-with-eureka: true
#需要检索服务
fetch-registry: true
#心跳检测检测与续约时间
instance:
#告诉服务端,如果我10s之内没有给你发心跳,就代表我故障了,将我剔除掉,默认90s
#Eureka服务端在收到最后一次心跳之后等待的时间上限,单位为秒,超过则剔除(客户端告诉服务端按照此规则等待自己)
lease-expiration-duration-in-seconds: 10
#每隔2s向服务端发送一次心跳,证明自已依然活着,默认30s
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(客户端告诉服务端自己会按照该规则)
lease-renewal-interval-in-seconds: 2
# 启用ip配置 这样在注册中心列表中看见的是以ip+端口呈现的
prefer-ip-address: true
# 实例名称 最后呈现地址:ip:2002
instance-id: ${spring.cloud.client.ip-address}:${server.port}
management:
endpoints:
web:
exposure:
include: ["info","health","refresh"]
8、码云仓库值默认如下
访问http://localhost:8881/index
访问http://localhost:8882/index
9、修改仓库内容
然后向springcloud-config-server服务bus-refresh端点发送POST请求http://localhost:8888/actuator/bus-refresh
10、再次访问客户端8881,882显示如下
三、指定刷新范围
在上面案例中我们看到当你触发/actuator/bus-refresh端点时,它就会刷新所有实例的服务配置,有时候我们可能只需要刷新某个具体的实例。
Spring Cloud Bus对这种场景也有很好的支持,/actuator/bus-refresh/{destination}接口提供了一个destination参数,RESTFUL风格请求,用来定位具体要刷新的应用程序。比如:我们可以请求/actuator/bus-refresh/springcloud-config-client:8882,此时总线上的各应用实例会根据destination属性的值来判断是否为自己的实例名,若符合才进行配置刷新,若不符合就忽略该消息。
destination参数除了可以定位具体的实例之外,还可以用来定位具体的服务。定位服务的原理是通过使用Spring的PathMatecher(路径匹配)来实现的,比如/actuator/bus-refresh/springcloud-config-client:**,该请求会触发customers服务的所有实例进行刷新。
1、以前仓库信息为:
例如:修改为如下
2、向http://localhost:8888/actuator/bus-refresh/springcloud-config-client:8882发送POST请求
3、访问客户端8881,8882服务内容如下
四、总结
使用/actuator/bus-refresh发送到我们其中一个config-client中也能刷新配置(前提是该客户端的bus-refresh端点需要暴露出来),但是这样这个实例就跟其他实例不一样了,它还额外承担了刷新配置的功能。所以,我们将发送post请求刷新配置的任务交由config-server配置服务中心来处理,这样所有服务实例都是对等的,由配置服务中心发送消息通知消息总线更新整个集群中的配置。这样,服务实例就不需要再承担触发配置更新的任务。尽可能让服务集群中的各个节点是对等的将来利于运维工作。
详细参考案例源码:https://gitee.com/coding-farmer/springcloud-learn
Spring Cloud第十二篇 | 消息总线Bus的更多相关文章
- Spring Cloud第十四篇 | Api网关Zuul
本文是Spring Cloud专栏的第十四篇文章,了解前十三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring C ...
- Spring Cloud(十二):分布式链路跟踪 Sleuth 与 Zipkin【Finchley 版】
Spring Cloud(十二):分布式链路跟踪 Sleuth 与 Zipkin[Finchley 版] 发表于 2018-04-24 | 随着业务发展,系统拆分导致系统调用链路愈发复杂一个前端请 ...
- Spring Cloud(十二)声名式服务调用:Feign 的使用(下)
前言 本文是对上一篇博文的扩充,很多平时用不到的特性就开始简略一写,Spring Cloud各版本之间的差距很大的,用不到的可能下一个版本就被kill掉了.由于笔者写本文开始的时候误解了Feign的继 ...
- Spring-cloud微服务实战【十】:消息总线Bus
回忆一下,在上一篇文章中,我们使用了分布式配置中心config来管理所有微服务的配置文件,那这样有没有什么问题?有,那就是无法配置文件无法自动更新,当我的git服务器上的配置文件更新后,不能同步更 ...
- Spring Cloud(十):服务网关 Zuul(路由)【Finchley 版】
Spring Cloud(十):服务网关 Zuul(路由)[Finchley 版] 发表于 2018-04-23 | 更新于 2018-05-09 | 通过之前几篇 Spring Cloud 中 ...
- 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探
SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...
- Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇
Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇 本文主要内容: 1:spring cloud整合Eureka总结 本文是由凯哥(凯哥Java:kagejava ...
- Spring Cloud 入门 之 Ribbon 篇(二)
原文地址:Spring Cloud 入门 之 Ribbon 篇(二) 博客地址:http://www.extlight.com 一.前言 上一篇<Spring Cloud 入门 之 Eureka ...
- Spring Cloud 入门 之 Config 篇(六)
原文地址:Spring Cloud 入门 之 Config 篇(六) 博客地址:http://www.extlight.com 一.前言 随着业务的扩展,为了方便开发和维护项目,我们通常会将大项目拆分 ...
随机推荐
- leetcode 240搜索二维矩阵
/** 正常的二维搜索估计要超时,本题沿着对角线搜索,然后找到第一个大于目标数字的坐标(x,y)然后搜索(>x,<y)(<x,>y)子区域: 矩阵size() 为m,n:当i& ...
- Vue项目移动端滚动穿透问题
概述 今天在做 Vue 移动端项目的时候遇到了滚动穿透问题,在网上查资料后,选取了我觉得最好的方法,记录下来供以后开发时参考,相信对其他人也有用. 上层无需滚动 如果上层无需滚动的话,直接屏蔽上层的 ...
- ubuntu16.04 卸载及安装MySQL
以MySQL- 5.7.18为例: sudo apt-get autoremove --purge mysql-server-5.7 #sudo apt-get remove mysql-server ...
- current_url 获取当前测试地址和page_souce获取当前网页源代码
from selenium import webdriverdriver = webdriver.Firefox()driver.get("https://www.baidu.com&quo ...
- iptables规则
iptables命令是Linux上常用的防火墙软件,是netfilter项目的一部分 iptables文件设置路径:命令:vim /etc/sysconfig/iptables-config 0x02 ...
- 《深入浅出WPF》学习总结之控件与布局
一.控件到底是什么 控件的本质是“数据+算法”——用户输入原始数据,算法处理原始数据并得到结果数据.问题就在于程序如何将结果数据展示给用户.同样一组数据,你可以使用LED阵列显示出来,或者是以命令行模 ...
- 简单的遍历xml
#include <opencv2\opencv.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv ...
- k线图的分形
蜡烛图上的分形指标,作为一种特殊的K线组合形态,通过对价格的一系列的高低点的描述,辅助识别出市场潜在的突破和反转点,预判后期走势. 顶分形:相邻的五根K线,若中间那根K线最高价为这五根K线的最高价,则 ...
- sql query执行的顺序
第一, from, 选择或者join多个表得到基础数据表,所以,联结是第一步要执行的操作,它在获取最基础的数据表: 第二,where,过滤掉基础数据表中不符合条件的行,得到后续操作的数据表: 第三, ...
- UUID与System.currentTimeMillis()产生一个新文件名的工具类
1.FileUtils.java package Utils.GenerateNewFileName; import java.util.UUID; public class FileUtils { ...