Hystrix简介
Hystrix是一个用于处理分布式系统的延迟和容错的开源库。在分布式系统中服务与服务的依赖中,总会出现失败的情况,如:Feign写的超时、异常、服务停止等等。
Hystrix能够保证在一个依赖出现问题的时候,不让导致整个服务的级联故障,以提高分布系统的弹性。通过断路器监控,给调用方返回一个预设的响应(Fallback)而不是直接报错。它会保证调用方的线程不会长时间占用,避免整个服务瘫痪。
Hystrix主要有3个部分
- 服务降级 如:返回自定义的提示,服务忙等可读性提示 Fallback 降级条件:程序异常、超时或者主动触发
- 服务熔断 如:服务器承受最大访问后,直接拒绝访问,调用降级方法返回可读性提示。 服务降级–>熔断–>恢复调用
- 服务限流 如:高并发等操作,禁止请求量过大拥挤,设定一个阈值,排队有序进行
代码演示
接着前面四篇文章,现在有4个服务:注册中心7000、消费者8001、生产者9001、生产者9002
在两个生产者pom中添加Hystrix依赖
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
从生产者实现降级
修改controller,增加service类,具体实现如下
生产者8001修改如下:
package com.cto.cloud.controller;
import com.cto.cloud.service.ProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
*
* @author Zhang Wei
* @date 2020/5/23 15:08
* @version v1.0.1
*/
@RestController
@RequestMapping("/provider")
public class IndexController {
@Autowired
private ProviderService providerService;
@GetMapping(value = "/getData")
public String getData(){
return providerService.getDataOk();
}
@GetMapping(value = "/getDataError")
public String getDataError(){
return providerService.getDataError();
}
}
添加的service
package com.cto.cloud.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
*
* @author Zhang Wei
* @date 2020/5/23 22:39
* @version v1.0.1
*/
@Service
public class ProviderService {
@Value("${server.port}")
private String port;
/**
* 正确返回
* @return
*/
public String getDataOk(){
return port + "\t getDataOk";
}
/**
* 故意异常
* @return
*/
@HystrixCommand(fallbackMethod = "getDateErrorFallBack",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
})
public String getDataError() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return port + "\t getDataError 等3秒";
}
public String getDateErrorFallBack(){
return "服务超时了,我只等你2秒";
}
}
启动类添加注解 @EnableCircuitBreaker
生产者8002修改
controller一样,service如下
package com.cto.cloud.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
*
* @author Zhang Wei
* @date 2020/5/23 22:39
* @version v1.0.1
*/
@Service
public class ProviderService {
@Value("${server.port}")
private String port;
/**
* 正确返回
* @return
*/
public String getDataOk(){
return port + "\t getDataOk";
}
/**
* 故意异常
* @return
*/
@HystrixCommand(fallbackMethod = "getDateErrorFallBack",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
})
public String getDataError() {
int i = 10/0; //计算异常
return port + "\t getDataError";
}
public String getDateErrorFallBack(){
return "服务异常啦,待会再试";
}
}
启动类添加注解 @EnableCircuitBreaker
消费者8001添加请求调用:
controller添加
@GetMapping(value = "/getDataError")
public Object getDataError(){
return providerService.getDataError();
}
service添加
@GetMapping("/provider/getDataError")
String getDataError();
顺序启动注册中心7000、消费者8001、生产者9001、生产者9002
访问http://localhost:8001/consumer/getDataError
9001返回

9002返回

至此,生产者端配置熔断可以看到,超时或者异常都会别拦截。
从消费者实现降级
修改Consumer8001 yml
#服务降级开启
feign:
hystrix:
enabled: true
这个默认值默认是false,这里配置为true
修改主启动类,添加注解 @EnableHystrix
添加一个公共的Hystrix统一返回类,实现ProviderService方法
package com.cto.cloud.service;
import org.springframework.stereotype.Component;
/**
*
* @author Zhang Wei
* @date 2020/5/23 23:57
* @version v1.0.1
*/
@Component
public class ProviderServiceHystrix implements ProviderService{
@Override
public String getData() {
return "服务异常了";
}
@Override
public String getDataError() {
return "服务异常了";
}
}
修改ProviderService 添加fallback
package com.cto.cloud.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author Zhang Wei
* @version v1.0.1
* @date 2020/5/18 20:42
*/
@Component
@FeignClient(value = "CLOUD-PROVIDER",fallback = ProviderServiceHystrix.class)
public interface ProviderService {
@GetMapping("/provider/getData")
String getData();
@GetMapping("/provider/getDataError")
String getDataError();
}
重启Consumer服务,接着降生产者服务器故意关闭模拟宕机
访问http://localhost:8001/consumer/getDataError

返回了自定义异常
服务熔断
修改生产者Provider 9002service
//服务熔断
@HystrixCommand(fallbackMethod = "getIdErrorFallBack",commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"), //是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), //请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), //时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50") //失败率达到多少
})
public String getId(Integer id) throws Exception {
if(id < 0){
throw new Exception("主动异常");
}
return port + "-----" + id;
}
public String getIdErrorFallBack(){
return port + "服务超时了,我只等你2秒";
}
controller
@GetMapping(value = "/getId/{id}")
public Object getId(@PathVariable("id") Integer id) throws Exception {
return providerService.getId(id);
}
启动注册中心、启动生产者9001
访问http://localhost:9001/provider/getId/1

访问http://localhost:9001/provider/getId/-1

疯狂的点击id为-1的请求10多次以后,切换ID为1,发现服务依旧会报熔断了,而经过访问几次,失败率下降以后服务恢复正常
服务熔断
熔断类型
1.熔断打开
请求不再进行调用当前服务,内部设置时钟(平均故障处理时间),当打开时长达到所设时钟则进入熔断状态
2.熔断关闭
熔断关闭不会对服务进行熔断
3.熔断半开
部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断
断路器开启或者关闭的条件
当满足一定阀值的时候(默认10秒内超过20个请求次数)
当失败率达到一定的时候(默认10秒内超过50%请求失败)
到达以上阀值,断路器将会开启
当开启的时候,所有请求都不会进行转发
一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5
Hystrix的工作流程详见官方文档说明:https://github.com/Netflix/Hystrix/wiki/How-it-Works#Flow
本文是在学习过程中整理,如有错误欢迎各位大佬指正!O(∩_∩)O
陆续更新中……
转载:https://blog.csdn.net/zyw562123314/article/details/106309118