SpringCloud-Bus消息总线
SpringCloud-Bus消息总线
在SpringCloud-Config里我们讲到了使用外部统一的配置(案例采用GitHub)来托管我们的配置文件。但是有个小问题,如何让他们修改一处就处处生效而不用每个微服务都去手动发一个post请求或者重启服务呢,这就需要用到我们的Bus消息总线了。所以一般他们两个都搭配起来使用的。
SpringCloudBus配合SpringCloudConfig使用可以实现配置的动态刷新。
Spring Cloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架
它整合了Java的事件处理机制和消息中间件的功能。
Spring Clud Bus目前支持RabbitMQ
和Kafka
。
在看下面的内容之前我建议你对RabbitMQ有一定的了解和认识。
什么是总线
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题, 并让系统中所有微服务实例都连接上来。由于该主题中产生的消 息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题 上的实例都知道的消息
基本原理
ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。
使用Bus
安装配置RabbitMQ,建议直接使用docker一气呵成。
具体我在这里已经写过了。大家可以看看。
继3355微服务之后,我们再创一个3366,为的就是让效果显著。
这里我就不介绍3355和3366了,因为在Config博客已经详细说过。
启动7001,3344,3355,3366,测试结果为正常。
我们将对3344这个微服务进行配置,因为它是直接与GitHub相连的,所以Bus广播做到这里最合适。
关于Bug广播的设计思想有两种
- 利用消息总线触发一个客户端/bus/refresh,而刷新所有客户端的配置
- 利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端的配置
我们将推荐并长期使用第二种,为什么第一种思想不合适呢,
- 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责。
- 破坏了微服务各节点的对等性。因为第一种,有一个客户端需要额外的承担刷新职责,而其他的客户端却只有业务职责有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改
对3344,3355,3366添加消息总线依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
修改3344的配置文件
spring:
rabbitmq:
host: 192.168.111.130 #ip
port: 5672 #默认就是5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
3355和3366的配置文件
spring:
rabbitmq:
host: 192.168.111.130 #ip
port: 5672 #默认就是5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
include: "*"
检查一下3355和3366控制类,必须加上注解@RefreshScope
我将贴出3355的完整代码,3366也是一样的。
package com.xn2001.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @author 乐心湖
* @date 2020/5/29 14:40
**/
@EnableEurekaClient
@SpringBootApplication
public class ConfigCenterMain3355 {
public static void main(String[] args) {
SpringApplication.run(ConfigCenterMain3355.class,args);
}
}
package com.xn2001.springcloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 乐心湖
* @date 2020/5/29 14:41
**/
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${config.info}")
private String configInfo; //要访问的3344上的信息
@Value("${server.port}")
private String port;
@GetMapping("/configInfo") //请求地址
public String getConfigInfo() {
return "t port:" + port + " text:" + configInfo;
}
}
#bootstrap.yml
server:
port: 3355
spring:
application:
name: config-client
cloud:
#Config客户端配置
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取 http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址 表示通过这个服务端访问
rabbitmq:
port: 5672 #默认就是5672
username: guest
password: guest
host: 192.168.111.130
#暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
#服务注册到eureka地址
eureka:
client:
register-with-eureka: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
启动7001和3344,再启动3355和3366,测试一下访问相关接口是否都正常。然后再继续往下。
我们把GitHub上面的配置文件改一改,就把后面的version=1改成5吧,下拉到绿色按钮保存。
重新访问:http://localhost:3344/master/config-dev.yml
可以看到这边已经同步了,但是此时3355和3366还没有同步,别着急。
我们只需要给http://localhost:3344/actuator/bus-refresh
发送一个post请求即可实现同步。
这里我直接使用cmd发送了,懒得去开postman。
命令是
curl -X POST "http://localhost:3344/actuator/bus-refresh"
然后访问http://localhost:3366/configInfo
和http://localhost:3355/configInfo
可以看到结果已经同步过来了。
上面我们是全局同步更新,下面介绍一下如何定点更新(就是只更新一个服务)
实现方法:cmd执行命令时后面带上全服务名,例如:
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"
再去GitHub修改一下version测试。
执行完命令结果可以看到3355同步更新,3366不同步更新。
- Linux系统下MongoDB的简单安装与基本操作
- Go语言同步(Synchronization)
- 服务器反爬虫攻略:Apache/Nginx/PHP禁止某些User Agent抓取网站
- 【Dev Club分享】JSPatch成长之路
- Node.js新手必须知道的4个JavaScript概念
- 博客文章重新启用评论,附一键填写评论中用户信息代码生成工具
- 提升 Node.js 应用性能的 5 个技巧
- 再次扩散:Linux系统bash漏洞CVE-2014-6271仍未被彻底修复,红帽再发补丁
- SEO分享:彻底禁止搜索引擎收录非首选域名的方法
- 紧急扩散:Linux系统bash严重安全漏洞CVE-2014-6271的检测及修复方法
- 手游热更新方案xLua开源:Unity3D下Lua编程解决方案
- WordPress评论滑动/拉链解锁myQaptcha代码版及部署方法
- 修改WordPress分类目录和页面链接以斜杠/结尾,附nginx对应的301跳转设置方法
- 彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 这款网络排查工具,堪称神器!
- 浙大版《C语言程序设计(第3版)》题目集 练习2-4 温度转换
- 浙大版《C语言程序设计(第3版)》题目集 练习2-6 计算物体自由下落的距离
- 浙大版《C语言程序设计(第3版)》题目集 练习2-8 计算摄氏温度
- 浙大版《C语言程序设计(第3版)》题目集 练习2-9 整数四则运算
- 浙大版《C语言程序设计(第3版)》题目集 练习2-10 计算分段函数[1]
- 浙大版《C语言程序设计(第3版)》题目集 练习2-11 计算分段函数[2]
- SAP Spartacus产品页面的normalizer
- Nodejs中使用net-snmp库读取智慧站房的温湿度、空调等实时数据
- 生气!面试官你过来,我给你手写一个Spring Aop实现!
- 浙大版《C语言程序设计(第3版)》题目集 练习2-12 输出华氏-摄氏温度转换表
- Linux下文本处理“三剑客”
- Thread和goroutine两种方式实现共享变量按序输出
- 浙大版《C语言程序设计(第3版)》题目集 练习2-13 求N分之一序列前N项和
- 浙大版《C语言程序设计(第3版)》题目集 练习2-14 求奇数分之一序列前N项和