Spring Cloud 系列(五) Netflix Hystrix

序号名称链接
1 Spring Cloud 系列(二) 配置中心-Confighttps://blog.csdn.net/qq_38130094/article/details/91456800
2Spring Cloud系列(三) Netflix Eureka注册中心https://blog.csdn.net/qq_38130094/article/details/93992709
3Spring Cloud 系列(四) Netflix ribbon负载均衡https://blog.csdn.net/qq_38130094/article/details/97240915
4Spring Cloud 系列(五) Netflix Hystrixhttps://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",//线程池名称,默认定义为groupKey
            fallbackMethod = "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

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值