Hystrix主要能为我们解决哪些问题

  • 服务降级:当一个服务出现宕机、超时、资源不足或者出现异常时,可以执行一个降级的方法,调用降级业务逻辑,返回一个托底的数据/响应。
  • 线程隔离:提供了一个Hystrix的线程池,以及信号量机制,帮助我们管理容器的线程池,或者实现与容器的线程池隔离。
  • 熔断:当一个请求的失败率,达到一定阈值的时候,启动熔断机制。
  • 请求缓存:缓存当前请求的信息,下次调用直接返回。
  1. 在customer里面导入pom依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

在启动类上加入这个注解 @EnableCircuitBreaker
在contrller中针对一个类进行降级

@GetMapping("/customer/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallBack")
public Customer findById(@PathVariable Integer id){
    int i = 1/0;
    return searchClient.findById(id);
}

// findById的降级方法  方法的描述要和接口一致
public Customer findByIdFallBack(Integer id){
    return new Customer(-1,"",0);
}
/customer/{id}是我方法请求的路径
findByIdFallBack 要和西安的降级方法名字
上面的方法和降级的方法是重写关系 如果成功返回return searchClient.findById(id);
失败则调用降级的方法

在接口上增加@HystrixCommand(fallbackMethod = “findByIdFallBack”)注解

线程隔离

1.线程隔离策略
  • Hystrix的线程池(默认):接收用户请求采用容器(tomcat)的线程池,执行业务代码时,调用其他服务时候采用Hystix的线程池。
  • 信号量:使用还是容器的线程池,他是使用信号量机制,帮我们管理容器的线程池。
  • 接口添加了@HystrixCommand注解,默认就是用了线程池的线程隔离策略。
2.配置信息
  • 线程隔离策略:hystrix.command.default.execution.isolation.strategy THREAD、信号量SEMAPHORE
  • 指定超时时间:配置了超时时间,调用其他服务或者执行业务代码总耗时超过该数值,则调用服务降级方法。
  • 默认配置:1000ms,该配置只针对线程池策略可用。
  • hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 1000

  • 是否启用超时时间:hystrix.command.default.execution.timeout.enabled true
  • 超时之后是否中断:hystrix.command.default.execution.isolation.thread.interruptOnTimeout true
  • 取消之后是否中断:hystrix.command.default.execution.isolation.thread.interruptOnCancel false(具体可以看GitHub官方文档)

代码实现部分

@GetMapping("/inset")
    @HystrixCommand(fallbackMethod = "findByIdFallBack",commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD"),
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
    })
    public int searcheById(@RequestBody Goods goods) throws InterruptedException {
        System.out.println("当前线程:"+Thread.currentThread().getName());
         Thread.sleep(5000);
        Goods goods1 = new Goods("榴莲往返",30,"斤","500",new Date(),new Date(),1);
        return serchClient2.insent(goods1);

    }
    public int findByIdFallBack1(Goods goods){
        return 0;
    }
    如果成功 创建对象 失败返回0  休眠了5秒 他默认3面肯定超时
断路器

断路器的工作原理
在调用指定服务时,如果说这个服务的失败率在指定的时间范围内(时间条件10秒)达到你输入的一个阈值,将断路器从closed状态,转变为open状态,指定服务时无法被访问的,如果你访问就直接走fallback方法,在一定的时间内,open状态会再次转变为half open状态,允许一个请求发送到我的指定服务,如果成功,转变为closed,如果失败,服务再次转变为open状态,会再次循环到half open,直到断路器回到一个closed状态。

2.配置断路器的监控界面

导入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

在启动类中添加注解
@@EnableHystrixDashboard//启用Hystrix图形化监控界面 豪猪页面

3.配置一个Servlet路径,指定上Hystrix的Servlet
@WebServlet("/hystrix.stream")
public class HystrixServlet extends HystrixMetricsStreamServlet {
}

//------------------------------------------------------------

在启动类上,添加扫描Servlet的注解
@ServletComponentScan(“com.qf.servlet”)

这个包是你定义@WebServlet("/hystrix.stream")
public class HystrixServlet extends HystrixMetricsStreamServlet {
}的包
访问:http://localhost:8080/hystrix.stream 进入豪猪页面
当出错会从cloued变为open你访问降级fallback方法时会从open变为half open状态在判断服务请求是否有错 有错继续open 位错变为cloued状态

断路器的配置
  • 是否启用断路器(开关):hystrix.command.default.circuitBreaker.enabled true
  • -失败阈值:hystrix.command.default.circuitBreaker.requestVolumeThreshold 20 意思就是每10秒钟之内失败的请求数达到20个,那么断路器就会打开(open状态)
  • 断路器open之后,所少毫秒达到半开状态,也就是多少毫秒之内是拒绝请求的:hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds 5000 默认是5秒
  • 请求总数达到多少时,断路器断开:hystrix.command.default.circuitBreaker.errorThresholdPercentage 50%
  • 强制让服务拒绝请求:hystrix.command.default.circuitBreaker.forceOpen false
  • 强制让服务接收请求:hystrix.command.default.circuitBreaker.forceClosed false
注意:forceOpen 和 forceClosed 互斥,同时只能配置一个为true

代码:

@GetMapping("/allbyid/{id}")
    @HystrixCommand(fallbackMethod = "findByIdFallBack",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),//断路器打开状态
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "3"),
            //1s请求3次便从cloued状态转为open状态
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "70"),
            //失败率达到70%
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "5000")//断路器open状态后 5秒拒绝请求
    })
    public String searcheById(@PathVariable Integer id) throws InterruptedException {
        System.out.println("当前线程:"+Thread.currentThread().getName());
        if(id==0){
            int i=0/0;
        }

        return serchClient2.querybyid(id).toString();

    }
    public String findByIdFallBack(Integer id){
        return "商品已经下架";
    }
    当我访问/allbyid/{id}时  成功正常显示数据  失败 return "商品已经下架"