概念
Bus可以用来干什么?
上一篇文章手动刷新每一次只能通知一个客服端,通知多个客服端就需要多次post请求更新不同的客服端。通过Bus我们就可以广播似的通知所有客服端,于是所有客服端都能同时读取到最新的配置信息。还可以通知对应的客服端,不需要通知的就不通知。
一般我们是通过bus和config配置中心来实现自动刷新。
方式一:简单理解就是通知一个客服端更新了,然后相互通知,其它客服端就知道配置已经跟新了(相互感染)
方式二:就是通知服务端,然后服务端告诉所有客服端配置已经更新了。
Bus支持两种消息代理:RabbitMQ和Kafka
基本原理:ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。(可以这样理解:一些客服端订阅了相同的微信公众号,只要公众号更新了,订阅了该公众号的客服端就能收到通知)
RabbitMQ环境配置
- 下载安装Erlang:http://erlang.org/download/otp_win64_21.3.exe
- 下载安装RabbitMQ
- 进入安装RabbitMQ的sbin目录 D:\softInstall\RabbitMQ\rabbitmq_server-3.7.15\sbin,然后cmd回出
- 在命令台输入rabbitmq-plugins enable rabbitmq _management命令
5.启动rabbitmq
浏览器中访问:http://localhost:15672/ 账户和密码默认就是guest。登录成功就表示环境搭建好了
示例
改造码云上面的配置文件
为了演示简单我们把远程配置文件application-client.yml 的dev模块的server:port: 9003删除配置到本地(这样不同的客服端通过不同的端口就能访问相同的配置)
spring:
profiles:
active: dev
---
spring:
profiles: dev
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
config:
info: "version=4"
---
server:
port: 9004
spring:
profiles: test
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
改造springcloud-config-client
- pom.xml
<!--配置rabbitMQ开始-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- application.yml 因为远程删掉了端口配置,所有我们需要配置到本地
server:
port: 9003
#rabbitmq相关配置 通过rabbitmq配置消息总线
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
- 其它代码见上篇文章
新建springcloud-config-client2作为第二个客服端 (代码几乎与springcloud-config-client一致)
- pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--配置rabbitMQ开始-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- bootstrap.yml
# 系统级别的配置
spring:
cloud:
config:
name: application-client # 需要从git上读取的资源名称,不要后缀
profile: dev
label: master #label
uri: http://localhost:9001 #此处连接服务端地址
- application.yml
server:
port: 9004
# 用户级别的配置
spring:
application:
name: springcloud-config-client2
#rabbitmq相关配置 通过rabbitmq配置消息总线
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
# 暴露监控的端点
management:
endpoints:
web:
exposure:
include: "*"
- controller
package com.dong.client2.controller;
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${spring.application.name}")
private String applicationName; //获取微服务名称
@Value("${eureka.client.service-url.defaultZone}")
private String eurekaServer; //获取Eureka服务
@Value("${server.port}")
private String port; //获取服务端的端口号
@Value("${config.info}")
private String info;
@RequestMapping("/config")
public String getConfig(){
return "applicationName:"+applicationName +"<br/>"+
"eurekaServer:"+eurekaServer +"<br/>"+
"port:"+port+"<br/>"+
"info"+info;
}
}
- 主启动类
package com.dong.client2;
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientTwoApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientTwoApplication.class,args);
}
}
改造:springcloud-config-server
我们使用消息总线通知更新推荐使用通知服务端,然后服务端通知客服端远程进行跟新的方式,接下来我们需要对服务端进行改进,其它代码见上篇文章
- pom.xml 需要通过rabbitMQ进行通知
<!--配置rabbitMQ开始-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!--actuator完善监控信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- application.yml 提醒:凡是要配置暴露端点,我们就需要actuator依赖
#rabbitmq相关配置 通过rabbitmq配置消息总线
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
management:
endpoints: #暴露bus刷新配置的端点
web:
exposure:
include: 'bus-refresh'
启动 eureka,springcloud-config-server,springcloud-config-client和springcloud-config-client2
访问:http://localhost:7001/ 两个客服端均已注册到eureka
访问:http://localhost:9003/config
applicationName:springcloud-config-client
eurekaServer:http://localhost:7001/eureka/
port:9003
infoversion=4
访问:http://localhost:9004/config
applicationName:springcloud-config-client2
eurekaServer:http://localhost:7001/eureka/
port:9004
infoversion=4
此时我们修改远程配置文件 version=5
通过服务端访问:http://localhost:9001/application-client-dev.yml
config:
info: version=5
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
spring:
profiles:
active: dev
我们发现version确实变为5了,但是此时两个客服端访问结果还是是4
然后我们需要以post方式访问http://localhost:9001/actuator/bus-refresh
最后我们在依此访问两个客服端,发现version成功变为5了【一处通知(service),处处生效(两个client)】
此时我们在登录rabbitmq,发现交换机生成了一个默认的topic springCloudBus。上面基本原理已经提到过
定点通知
现在我只想通知9003,不通知9004.
我们修改远程配置文件内容version=6
以post的方式访问:http://localhost:9001/actuator/bus-refresh/application-client:9003
application-client是指客服端spring.application.name,9003是指要通知的客服端的端口号
访问:http://localhost:9004/config
applicationName:springcloud-config-client2
eurekaServer:http://localhost:7001/eureka/
port:9004
infoversion=5
访问:http://localhost:9003/config
applicationName:springcloud-config-client
eurekaServer:http://localhost:7001/eureka/
port:9003
infoversion=6
通过上面的结果表明成功的实现了定点刷新通知
参考教程尚硅谷