Spring Cloud Bus服务总线
问题
前面已经完成了将微服务中的配置文件集中存储在远程Git仓库,并且通过配置中心微服务从Git仓库拉取配置文件,当用户微服务启动时会连接配置中心获取配置信息从而启动用户微服务。如果我们更新Git仓库中的配置文件,那用户微服务是否可以及时接收到新的配置信息并更新呢?
1. 修改远程Git配置
修改在码云上的userservice-dev.yml文件,添加一个属性test.name。
2.修改UserController
package com.pjh.user.Controller;
import com.pjh.user.Service.UserService;
import com.pjh.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@Value("${test.name}")
private String name;
@GetMapping("/{id}")
public User queryById(@PathVariable Long id) throws InterruptedException {
System.out.println("配置文件中的文件名为:"+name);
return userService.queryForId(id);
}
@RequestMapping("/test")
@ResponseBody
public String test(){
return "Hello word!!";
}
}
测试
依次启动注册中心 eureka-server 、配置中心 config-server 、用户服务 user-service ;然后修改Git仓库中的配置信息,访问用户微服务,查看输出内容。
结论:通过查看用户微服务控制台的输出结果可以发现,我们对于Git仓库中配置文件的修改并没有及时更新到用户微服务,只有重启用户微服务才能生效。
如果想在不重启微服务的情况下更新配置该如何实现呢? 可以使用Spring Cloud Bus来实现配置的自动更新。
需要注意的是Spring Cloud Bus底层是基于RabbitMQ实现的,默认使用本地的消息队列服务,所以需要提前启动本地RabbitMQ服务(安装RabbitMQ以后才有),如下:
Spring Cloud Bus简介
概述
Spring Cloud Bus是用轻量的消息代理将分布式的节点连接起来,可以用于广播配置文件的更改或者服务的监控管理。也就是消息总线可以为微服务做监控,也可以实现应用程序之间相互通信。 Spring Cloud Bus可选的消息代理有RabbitMQ和Kafka。
使用了Bus之后:
1.改造配置中心
1.导入相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
2.修改application.yml配置文件
server:
port: 1200
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
spring:
application:
name: Config-userservice
cloud:
config:
server:
git:
uri: https://gitee.com/mokeythree/eureka-test-config.git
#配置rabbitmq
rabbitmq:
host: ip#替换称你所有安装的rabbitmq对应服务器的地址
port: 5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
#暴露触发消息总线的地址
include: bus-refresh
改造用户服务
1.添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.修改bootstrap.ym 配置文件
server:
port: 8099
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
spring:
application:
name: consumer-eureka
#配置rabbitmq
rabbitmq:
host: 121.196.111.120 #替换称你所有安装的rabbitmq对应服务器的地址
port: 5672
username: guest
password: guest
ribbon.:
ConnectTimeout: 1000 # 连接超时时长
ReadTimeout: 2000 # 数据通信超时时长
MaxAutoRetries: 0 # 当前服务器的重试次数
MaxAutoRetriesNextServer: 0 # 重试多少次服务
OkToRetryOnAllOperations: false # 是否对所有的请求方式都重试
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds=2000
logging:
level:
com.pjh: debug
feign:
hystrix:
enabled: true
3.改造用户微服务 user-service 项目的UserController
package com.pjh.user.Controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.pjh.user.pojo.user;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("/consumer")
@RefreshScope//刷新配置
/*@DefaultProperties(defaultFallback ="queryByIdFallBack" )*/
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired(required = false)
private DiscoveryClient discoveryClient;
@GetMapping("/{id}")
@HystrixCommand(defaultFallback = "queryByIdFallBack")
public String QueryForId(@PathVariable String id){
if (Integer.parseInt(id)==1){
throw new RuntimeException("太忙了");
}
/* String url = "http://localhost:8088/user/" + id;
*//*获取eureka中注册的user-service实例列表*//*
List<ServiceInstance> instancesList = discoveryClient.getInstances("producer-service");
ServiceInstance serviceInstance = instancesList.get(0);
url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort()
+ "/user/" + id;*/
String url = "http://producer-service/user/" + id;
return restTemplate.getForObject(url, user.class).toString();
}
public String queryByIdFallBack(){
return "网络拥挤请稍后再试!!";
}
}
测试
前面已经完成了配置中心微服务和用户微服务的改造,下面来测试一下,当我们修改了Git仓库中的配置文件,用户
微服务是否能够在不重启的情况下自动更新配置信息。
**
测试步骤:
第一步:依次启动注册中心 eureka-server 、配置中心 config-server 、用户服务 user-service
第二步:访问用户微服务http://localhost:9091/user/8;查看IDEA控制台输出结果
第三步:修改Git仓库中配置文件 user-dev.yml 的 test.name 内容
第四步:使用Postman或者RESTClient工具发送POST方式请求访问地址http://127.0.0.1:12000/actuator/bus-refresh
第五步:访问用户微服务系统控制台查看输出结果
**
说明:
1、Postman或者RESTClient是一个可以模拟浏览器发送各种请求(POST、GET、PUT、DELETE等)的工具
2、请求地址http://127.0.0.1:12000/actuator/bus-refresh中 /actuator是固定的,/bus-refresh对应的是配置中心config-server中的application.yml文件的配置项include的内容
3、请求http://127.0.0.1:12000/actuator/bus-refresh地址的作用是访问配置中心的消息总线服务,消息总线服务接收到请求后会向消息队列中发送消息,各个微服务会监听消息队列。当微服务接收到队列中的消息后,会重新从配置中心获取最新的配置信息。
Spring Cloud 体系技术综合应用概览