当前位置: 代码迷 >> 综合 >> Spring Cloud 系列(五) Netflix Hystrix
  详细解决方案

Spring Cloud 系列(五) Netflix Hystrix

热度:46   发布时间:2023-12-06 10:36:01.0
序号 名称 链接
1  Spring Cloud 系列(二) 配置中心-Config https://blog.csdn.net/qq_38130094/article/details/91456800
2 Spring Cloud系列(三) Netflix Eureka注册中心 https://blog.csdn.net/qq_38130094/article/details/93992709
3 Spring Cloud 系列(四) Netflix ribbon负载均衡 https://blog.csdn.net/qq_38130094/article/details/97240915
4 Spring Cloud 系列(五) Netflix Hystrix https://blog.csdn.net/qq_38130094/article/details/97626558

1. Hystrix简介

Hystrix是Netflix开源的一款承兑分布式系统的延迟和容错库,目的是用来隔离分布式服务故障。它提供了线程和信号量隔离,以减少不同服务之间的资源竞争带来的相互影响;提供了优雅的降级机制;提供了熔断机制,使得服务可以快速失败,而不是一直阻塞等待服务响应,并能从中快速恢复。Hystrix通过这些机制来阻止级联失败并保证系统弹性、可用。

2、Hystrix的作用

2.1解决的问题:

1: 限制调用分布式服务的资源使用,当某一个调用的服务出现问题不会影响其他服务调用, 通过线程隔离和信号量隔离实现;

2:Hystrix提供了优雅降级机制:超时降级、资源不足时(线程或者信号量)降级,降级后可 以配合降级接口返回托底数据;

3:Hystrix提供了熔断器实现,当失败率达到阈值自动触发降级(如因网络故障或超时造成的 失败率高),熔断器触发的快速失败会进行快速恢复;

4:提供了请求缓存和请求合并实现;

 

2.2 线程隔离

将Tomcat线程处理的任务转交给Hystrix内部的线程去执行,这样Tomcat线程就可以去 做其他事情。当Hystrix的线程将任务执行完成后,将执行结果返回给Tomcat线程。

1:功能:线程隔离

2:目的:管理线程资源,保证线程不会泛滥最终目的是为了保护服务节点  保障 可用性

3:场景:并发(并发量小一点的场景)的场景 都可以使用

4:走降级的会执行 fallback 方法:

作用:兜底数据/降级 从其他地方给你一个结果,比如redis

当无法获得可用核心线程数时,Hystrix直接在主线程中调用fallback()方法,执行降级逻辑。

2.3 信号量隔离

信号量隔离只是起到一个开关的作用,例如:服务X的信号量大小为10,那么同时只允许10个tomcat线程来访问服务X,其他的请求服务X,其他的请求 将被拒绝,从而达到限流保护的作用

       //1 :HystrixCommand 命令所属的组的名称:默认注解方法类的名称
        String groupKey() default "";

        //2 :HystrixCommand 命令的key值,默认值为注解方法的名称
        String commandKey() default "";

        //3 :线程池名称,默认定义为groupKey
        String threadPoolKey() default "";
        //4 :fallbackMethod 定义回退方法的名称, 此方法必须和hystrix的执行方法在相同类中
        String fallbackMethod() default "";
        //5 :配置hystrix命令的参数
        HystrixProperty[] commandProperties() default {};
        //6 :commandProperties配置hystrix依赖的线程池的参数
        HystrixProperty[] threadPoolProperties() default {};

        //5:如果hystrix方法抛出的异常包括RUNTIME_EXCEPTION,则会被封装HystrixRuntimeException异常。我们也可以通过此方法定义哪些需要忽略的异常
        Class<? extends Throwable>[] ignoreExceptions() default {};

        //6:定义执行hystrix observable的命令的模式,类型详细见ObservableExecutionMode
        ObservableExecutionMode observableExecutionMode() default ObservableExecutionMode.EAGER;

        //7:如果hystrix方法抛出的异常包括RUNTIME_EXCEPTION,则会被封装HystrixRuntimeException异常。此方法定义需要抛出的异常
        HystrixException[] raiseHystrixExceptions() default {};

        //8:定义回调方法:但是defaultFallback不能传入参数,返回参数和hystrix的命令兼容
        String defaultFallback() default "";

//线程隔离:使用该方式,HystrixCommand将会在单独的线程上执行,并发请求受线程池中线程数量的限制。@GetMapping("/testThread")@HystrixCommand(groupKey = "ThreadPoolGroupKey",//HystrixCommand 命令所属的组的名称:默认注解方法类的名称commandKey = "ThreadPoolCommandKey",//命令的key值,默认值为注解方法的名称threadPoolKey = "ThreadPoolKey",//线程池名称,默认定义为groupKeyfallbackMethod = "fallbackMethod",//定义回退方法的名称, 此方法必须和hystrix的执行方法在相同类中// 配置hystrix命令的参数commandProperties = {//降级处理超时时间@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="1000"),//该属性用来配置HystrixCommand.run()的执行是否启用超时时间。默认为true@HystrixProperty(name="execution.timeout.enabled", value="true"),//执行的隔离策略。默认为THREAD@HystrixProperty(name="execution.isolation.strategy", value="THREAD")}, threadPoolProperties = {//核心线程数@HystrixProperty(name="coreSize",value="15")})public String testThread(){try {int m = new Random().nextInt(1200);System.out.println("Thread sleep "+m+" ms");//与Thread.sleep();是一样的只是对时间进行了封装(枚举)增加可读性TimeUnit.MILLISECONDS.sleep(m);} catch (InterruptedException e) {e.printStackTrace();}return "Thread Pool";}/*** (信号量隔离):使用该方式,HystrixCommand将会在调用线程上执行,开销相对较小,并发请求受到信号量个数的限制。 * @return*/@GetMapping("/testSemaphore")@HystrixCommand(groupKey = "SemaphoreGroupKey",commandKey = "SemaphoreCommandKey",threadPoolKey = "SemaphoreThreadPoolKey",fallbackMethod = "fallbackMethod",commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="1000"),@HystrixProperty(name="execution.timeout.enabled", value="true"),@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE"),@HystrixProperty(name="execution.isolation.semaphore.maxConcurrentRequests", value="3"),@HystrixProperty(name="fallback.isolation.semaphore.maxConcurrentRequests", value="1")})public String testSemaphore(){try {int m = new Random().nextInt(1200);System.out.println("Thread sleep "+m+" ms");TimeUnit.MILLISECONDS.sleep(m);} catch (InterruptedException e) {e.printStackTrace();}return "Semaphore";}

3. 两种模式对比

1:线程池隔离对每个服务,使用单独的线程池

2:信号量隔离使用信号量计数器

3:线程池隔离模式消耗资源大,大量的线程上下文切换

4:信号量隔离模式资源消耗小,只是一个计数器。

  线程隔离 信号量隔离
线程 与调用线程非相同线程 与调用线程相同(容器线程)
开销 排队,调度,上下文开销 无线程切换,开销低
异步 支持 不支持
并发支持 支持(最大线程池大小) 支持(最大信号量上限)

 

四,Hystrix服务降级

当请求出现了异常,超时或者服务不可用等情况下,Hystrix可以自定义降级策略,防止直接返回空或者抛出异常。

当触发服务降级后会执行fallbackMethod();方法;

注:当抛出HystrixBadRequestException异常不会触发降级。

 

 

5.服务熔断

熔断也叫过载保护,一般指软件系统中,由于某些原因,服务出现了过载现象,为了防止造成整个系统故障,从而采用一种保护措施,如果某个服务调用慢或者有大量超时,Hystrix熔断该服务的调用,对于后续调用请求不在继续调用目标服务,直接返回,快速释放资源,如果目标服务情况好转则恢复调用。

核心:

1:在滚动时间窗口内,如果没有接收到指定最少请求个数,即使所有请求都失败,也不会打断路由

2:要满足时间\请求数\失败比例三个条件,触发熔断

3:当熔断后,fallback流程由main线程执行,一定时间后重新恢复,尝试执行主业务流程。

 @GetMapping("/testCircuitBreaker")@HystrixCommand(groupKey = "CircuitBreakerGroupKey",commandKey = "CircuitBreakerCommandKey",threadPoolKey = "CircuitBreakerThreadPoolKey",fallbackMethod = "fallbackMethod",threadPoolProperties = {@HystrixProperty(name="coreSize",value="200")},commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="1000"),@HystrixProperty(name="execution.timeout.enabled", value="true"),@HystrixProperty(name="circuitBreaker.enabled",value="true"),@HystrixProperty(name="metrics.rollingStats.timeInMilliseconds",value="10000"),@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="8"),@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="50"),@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="5000")})public String testCircuitBreaker(){try {int value = new Random().nextInt(10);System.out.println("Random value "+value);if(value % 3 !=0){while(true){}}else{System.out.println("secuss for "+value);}} catch (Exception e) {e.printStackTrace();}return "CircuitBreaker";}

6.请求缓存

Hystrix可将请求进行缓存,当后续有相同的请求时,直接返回缓存中的响应,从而避免直接对服务进行调用,增加服务的压力

7.请求合并

Hystrix可以在毫秒级别的请求做合并,但是感觉官方并不推荐使用(在官方的Hystrix的流程图中未给出请求合并)

 

hystrix工作流程图

 

参考:https://github.com/Netflix/Hystrix/wiki

 

 

 

  相关解决方案