参考
史上最简单的SpringCloud教程 | 第四篇:断路器(Hystrix)
在微服务架构中,一个请求需要调用多个服务是非常常见的,较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。
断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值
加入依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-hystrixartifactId>
dependency>
在启动类上添加@EnableHystrix注解开启Hystrix,然后在你需要实现断路器的service的方法上
加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "hiError")
public String hiService(String name) {
return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
}
public String hiError(String name) {
return "hi,"+name+",sorry,error!";
}
}
通过ribbon调用开启和关闭状态下的服务,可以看出服务关闭或故障时会调用短路指定的hiError方法
不需要eureka也可以正常生效
Feign是自带断路器的,默认没有打开
feign:
hystrix:
enabled: true
只需要在接口实现类注解中加上fallback的指定类就行了
@FeignClient(value = “service-hi”,fallback = SchedualServiceHiHystric.class)
需要实现 接口
@Component
public class SchedualServiceHiHystric implements SchedualServiceHi {
@Override
public String sayHiFromClientOne(String name) {
return "sorry "+name;
}
}
个人感觉还是用@EnableCircuitBreaker+@HystrixCommand的方式更方便一点儿,因为可以为每个方法定义不同的断路方法,至于feign需要为整个方法类定义一个断路类,感觉有点麻烦
Hystrix Dashboard是作为断路器状态的一个组件,提供了数据监控和友好的图形化界面。
在feign或ribbon 或不使用这两者都是如下操作
需要三个依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-hystrixartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-hystrix-dashboardartifactId>
dependency>
启动类加两个注解
@EnableCircuitBreaker @EnableHystrixDashboard
并且需要在类中声明断路点,如
@RequestMapping("/hi")
@HystrixCommand(fallbackMethod = "hiError")
public String home(@RequestParam String name) {
return "hi "+name+",i am from port:" +port;
}
public String hiError(String name) {
return "hi,"+name+",sorry,error!";
}
当访问hystrix.stream后你会发现一直在ping,如果你调用接口后会看到
表单填如下地址访问下接口,不然就是一直loading
http://localhost:8764/hystrix.stream title随便,然后调用接口
或者这种调用完接口,输入类似localhost:8762/hystrix.stream/hi?name=forezp亦可
在实际中往往不只要看一个服务的Hystrix Dashboard数据,要想看这个系统的Hystrix Dashboard数据就需要用到Hystrix Turbine,Hystrix Turbine将每个服务Hystrix Dashboard数据进行了整合。
我们可以按上面的Hystrix Dashboard配置创建多一个Hystrix Dashboard,即目前有servicehi和servicehi3
Hystrix Turbine的使用非常简单,只需要引入相应的依赖和加上注解和配置就可以了,创建一个新的module service-turbine,引入依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-turbineartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-netflix-turbineartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
启动类加上注解@EnableTurbine,开启turbine,@EnableTurbine注解包含@EnableDiscoveryClient注解,即开启了注册服务
在application.yml中配置
spring:
application.name: service-turbine
server:
port: 8769
security.basic.enabled: false
turbine:
aggregator:
clusterConfig: default # 指定聚合哪些集群,多个使用","分割,默认为default。可使用http://.../turbine.stream?cluster={clusterConfig之一}访问
### 配置Eureka中的serviceId列表,表明监控哪些服务
appConfig: service-hi,service-hi3
clusterNameExpression: new String("default")
# 1. clusterNameExpression指定集群名称,默认表达式appName;此时:turbine.aggregator.clusterConfig需要配置想要监控的应用名称
# 2. 当clusterNameExpression: default时,turbine.aggregator.clusterConfig可以不写,因为默认就是default
# 3. 当clusterNameExpression: metadata['cluster']时,假设想要监控的应用配置了eureka.instance.metadata-map.cluster: ABC,则需要配置,同时turbine.aggregator.clusterConfig: ABC
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
依次开启eureka-server、service-hi、service-hi3、service-turbine工程
打开http://localhost:8769/turbine.stream,界面如下:
依次请求:
http://localhost:8762/hi?name=forezp
http://localhost:8763/hi?name=forezp
打开:http://localhost:8763/hystrix或8732的都可以只要配置了Hystrix Dashboard,输入监控流http://localhost:8769/turbine.stream,点击monitor stream 进入页面,可以看到这个页面聚合了2个service的hystrix dashbord数据
多次访问两个接口可以发现数据会有变化,说明生效了