SpringCloud学习--- Hystrix详解(附代码包)

Posted 小样5411

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud学习--- Hystrix详解(附代码包)相关的知识,希望对你有一定的参考价值。

前言

上一篇:Feign详解

Hystrix是什么?Hystrix出现目的是为了解决服务雪崩的问题,服务雪崩就是客户端发送一个请求,服务A接到请求,可能还要去请求B,B可能还会请求C,C会请求D,某一时刻C宕机,可能会导致整个功能全部失效。从而导致回传给服务端的响应也出现问题,这就是服务雪崩。

Hystrix解决服务雪崩有四种方式:
1、降级:图中说明了会执行降级方法返回一个托底数据,也就是上一篇讲的fallback返回的异常信息,如浏览器打印 -> 出现问题了!!!
2、隔离:举个例子详细解释,如果客户端对A发送请求(A是Tomcat容器),tomcat会让其内部的一个线程池接收,一个请求过来就要一个线程池接收,如果tomcat中线程池用光了,客户端又发送过来一个请求,那么tomcat根本没有多余线程池去处理,业务逻辑代码根本就执行不了。Hystrix隔离提供了一个Hystrix线程池,和Tomcat线程池相互隔离,接收请求还是Tomcat线程池去做,但是处理业务就由Hystrix线程池去做。这样就不会出现业务逻辑代码处理不了情况。
3、熔断:比如服务B给服务C发送10个请求,8个都失败达到某一阈值),那么就认定这个服务C出现问题,触发熔断,以后服务B或者其他服务,就不会给服务C发送请求了,因为就像知道它已经没用了。
4、缓存:会把已经处理的请求缓存,如果下次遇到相同请求就直接用缓存。

一、降级

第一步:导入依赖、启动类添加@EnableCircuitBreaker开启降级

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

第二步:定义普通降级方法findByIdFallBack,也就是调用方法出现问题就会调用这个降级方法返回一个托底数据,比如返回字符串"出现问题了",或者{code=404,msg=“error”}字符串

二、隔离

线程隔离有两种实现
1、Hystrix线程池(默认):执行业务逻辑代码使用Hystrix线程池,与Tomcat线程池隔离,即使Tomcat线程执行请求卡顿也不会影响业务执行,因为业务执行由Hystrix线程池负责,归纳就是Tomcat线程池负责接收请求,Hystrix线程池负责处理业务。导入Hystrix依赖就默认在用Hystrix线程池。
2、信号量:不使用Hystrix线程池,用信号量管理Tomcat线程池,如果线程无可用的,就会让请求排队

2.1 Hystrix线程池配置

配置也简单,就是CustomerController加一个commandProperties,线程隔离策略value写Thread,表示线程池方式配置,下面是超时发生降级的时间,超过3s就调用降级方法,我们可以在findById中写一个Thread.sleep(3000);让其超时,看是否调用了降级方法返回托底数据

删除Thread.sleep(3000),重新执行,还是能显示正常结果

如果你加入一个打印线程,就会发现执行业务逻辑代码用的是hystrix线程池

2.2 信号量配置

信号量配置只要写value=SEMAPHORE,它不可以指定超时时间,通过指定最大并发请求数来触发降级

可以试着打印看一下,是否用的是tomcat线程,nio-8080表示Tomcat的端口,用的是Tomcat线程池

主要熟悉Hystrix线程池方式

三、熔断

正常情况断路器是关闭的,服务B给服务C发送10个请求,8个都失败(达到某一阈值),那么就认定这个服务C出现问题,触发熔断,断路器就会打开,以后服务B或者其他服务,就不会给服务C发送请求了,因为就像知道它已经没用了,直接fallback降级返回托底数据。每隔一定时间周期,其他服务会给之前宕机的服务C发送一个请求尝试,看看是否能得到响应,如果能,证明服务C又恢复了,这时断路器就会关闭,如果不能得到响应,证明服务还是宕机的,断路器依然保持开启,继续熔断这个服务C,不让其他服务对其访问。

阈值和每隔多少时间,都需要配置

3.1 配置断路器属性与监控界面

配了这么久应该知道套路了,1、依赖 2、yml文件 3、启动类 4、controller基本就是这样

第一步:导入依赖(customer模块导入)

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

第二步:yml文件,可视化界面配置

hystrix:
  dashboard:
    proxy-stream-allow-list: "localhost"

第三步:
为了显示可视化界面,需要配一个Servlet

@WebServlet("/hystrix.stream")
public class HystrixServlet extends HystrixMetricsStreamServlet {
}

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;

import javax.servlet.annotation.WebServlet;

@WebServlet("/hystrix.stream")
public class HystrixServlet extends HystrixMetricsStreamServlet {
}

开启监视界面,并且配置@ServletComponentScan(“com.yx.servlet”),这是为了让Spring扫描到刚刚写的Servlet

@GetMapping("/customer/{id}")
    @HystrixCommand(fallbackMethod = "findByIdFallBack",commandProperties = {
            @HystrixProperty(name="circuitBreaker.enabled",value = "true"),
            @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "10"),
            @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "70"), //表示失败百分比,70%,10个请求有7个失败就触发熔断,10s内达到70%
            @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "5000") //每隔几秒发送一个请求试探服务是否恢复
    })
    public Order findById(@PathVariable Integer id) {
        System.out.println(Thread.currentThread().getName());
        if (id==1){
            int i = 1/0;
        }

        return payClient.findById(id);
    }

解释配置注解

circuitBreaker.enabled = true	#断路器(circuitBreaker)开关
circuitBreaker.requestVolumeThreshold	#失败阈值请求数
circuitBreaker.errorThresholdPercentage	#请求失败率,比如requestVolumeThreshold=10,errorThresholdPercentage=70,就是7个失败就触发短路
circuitBreaker.sleepWindowInMilliseconds #断路后多少秒内是拒绝请求的

我们启动customer
浏览器输入http://localhost:8080/hystrix,然后输入框输入如下,因为配Servlet时注解是/hystrix.stream,所以输入这个,点监控Monitor Stream


断路器CircuitBreaker是默认关闭的,官方说10s内达到阈值就会触发短路,那我们新建浏览器窗口快速刷新10次,10s内10次以上http://localhost:8080/customer/1,id=1代码会1/0异常,刷10次就达到配置的断路要求,断路器触发打开


然后等5秒输入正确的http://localhost:8080/customer/2,断路器又可变为Closed,circuitBreaker.sleepWindowInMilliseconds #断路后多少秒内是拒绝请求的,5s内可能还拒绝请求,所以5s后再输入不是异常的

四、缓存

这个Hystrix缓存有点鸡肋,因为它只针对一次请求内的数据缓存,缓存当前线程中的一个方法,如果是第二次请求和第一次一样,也获取不到第一次的缓存,一般不用,不过多解释,缓存还是Redis、MongoDB用的多

代码
链接:https://pan.baidu.com/s/17We2B2I_Q45a5lI2ty5gOw
提取码:dmjm

以上是关于SpringCloud学习--- Hystrix详解(附代码包)的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud第二季之Hystrix,GateWay,Config以及Bus学习笔记

SpringCloud第二季之Hystrix,GateWay,Config以及Bus学习笔记

SpringCloud——Eureka Feign Ribbon Hystrix Zuul等关键组件的学习与记录

SpringCloud学习系列-Hystrix断路器

SpringCloud 学习笔记总结

SpringCloud 学习笔记总结