乐趣区

关于hystrix:hystrix使用示例

hystrix 三种降级策略,别离是:

  • 熔断触发降级
  • 超时触发降级
  • 资源隔离触发降级,又分了线程池与信号量两种

上面联合示例别离介绍下。

一,熔断触发降级

1,当某个服务失败率达到肯定限度时将开启熔断器,这个服务后续再被调用时会被间接拒绝执行 fallback 逻辑(被调用方服务呈现了问题,调用方进行熔断)
2,熔断器关上的两个条件

  1. 申请数达到设定的阀值
  2. 申请谬误占比达到设定的阀值

3,示例

    /**
     * HystrixProperty 的参数可参考 hystrixCommandProperties
     * 熔断触发降级
     * @return
     * 10s 内当发动了超过 5 次申请,且失败率超过 50%,熔断主动开启,* 从熔断开启到后续 5s 之内的申请,都不会进入到办法里,并
     * 且间接触发 fallback 这个回调办法返回。*/
    @GetMapping("/circuitBreaker/{num}")
    @HystrixCommand(commandProperties  = {
            // 开启熔断器性能
            @HystrixProperty (name = "circuitBreaker.enabled" ,value = "true"),
            // 设置最小申请数
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value ="5"),
            // 熔断工夫 5 秒
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds" , value ="5000"), 
            // 谬误流程比例
             @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50") 

    } ,fallbackMethod = "fallback")
    public String circuitBreaker(@PathVariable("num")int num){if(num%2==0){return "失常拜访";}

        throw new RuntimeException("");
    }
    // 入参加申请办法入参需统一
    public String fallback(int num){return "熔断触发降级";}

关上熔断器开关

@SpringBootApplication
@EnableCircuitBreaker
public class App {public static void main(String[] args) {SpringApplication.run(App.class,args);
    }

}

这个示例当申请次数超过 5 次也就是第 6 次的时候,如果错误率超过了 50% 则会关上熔断器并进入 fallback 逻辑,且熔断器在关上的 5s 内都会执行 ballback 逻辑。

二,超时触发降级

1,当某个服务拜访工夫超过指定工夫,可认为这个服务曾经失败而不会持续期待,而后降级返回。

2,示例

    /**
     * 超时工夫触发降级
     * @return
     */
    @GetMapping("/timeOut")
    @HystrixCommand(commandProperties  = {
        // 启动超时触发降级
        @HystrixProperty(name = "execution.timeout.enabled" , value = "true"),
        // 超过 1s 就触发降级
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds" , value = "1000"),
    } ,fallbackMethod = "fallback")
    public String timeOut() throws InterruptedException {Thread.sleep(3000) ;
        return "失常拜访";

    }


    public String fallback(){return "触发降级";}

三,资源隔离触发降级

1,资源隔离触发降级分两种:线程池与信号量,hystrix 默认应用的是线程池

再来看下信号量

信号量是限度申请并发数,如果超过了设定的值则触发降级。信号量的特点是应用容器 (如 tomcat) 的线程解决申请,不波及线程的高低切换,因为没有超时机制,所以适宜不依赖内部服务的场景。

     public String fallback(){return "触发降级";}

    @GetMapping("/semaphore")
    @HystrixCommand(
            commandProperties = {
                    // 隔离形式,有信号量与线程池两种
                    @HystrixProperty(name = "execution.isolation.strategy" , value = "SEMAPHORE"),
                    // 信号量大小,默认为 10,倡议 500-1000.
                    // 这里示意这个服务同时不能超过 2 个并发申请
                    @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests" , value = "2") 
            },
            fallbackMethod = "fallback"
    )
    public String semaphore() throws InterruptedException {return "semaphore 失常拜访";}

再来看下线程池的形式

hystrix 将须要被隔离的资源或服务形象成一个 command 对象,而后应用设定好的且独立的线程池执行,这样就不会影响到其它的服务。
线程池隔离的一个特点是在容器 (如 tomcat) 线程之外创立了新的线程池,也就须要额定的保护这个线程池,这会有肯定的开销(但官网的测试报告说开销并不大)。

 private int num1 = 1;
   
@HystrixCommand(
            commandProperties = {
                    // 应用线程池的隔离
                    @HystrixProperty(name = "execution.isolation.strategy" , value = "THREAD"),  
                    // 超时设置为 3 秒
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds" , value = "3000"),  

            },
            threadPoolProperties = {
                    // 线程池大小
                    @HystrixProperty(name = "coreSize" , value = "20"), 
                    // 期待队列长度
                    @HystrixProperty(name = "maxQueueSize" , value = "1000"),     
                    // 线程存活工夫
                    @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),
                    /**
                     * 即便 maxQueueSize 没有达到,达到
                     * queueSizeRejectionThreshold 该值后,* 申请也会被回绝。因为 maxQueueSize 不能被动静批改,* 这个参数将容许咱们动静设置该值
                     */
                    @HystrixProperty(name = "queueSizeRejectionThreshold" , value = "800"),  
            },
            groupKey = "ThreadService", commandKey = "thread" ,threadPoolKey = "ThreadService",
            fallbackMethod = "fallback"
            )
    public void  thread() throws  Exception  {Thread.sleep(1000);
        System.out.println(Thread.currentThread() + "失常拜访" + num1++);
    }



    public void fallback(){System.out.println("熔断工夫:" + new Date());
    }

须要留神下的是‘超时工夫’timeoutInMilliseconds,示例中设置的是 3s,应用的时候可能会在第 4s 的时候才熔断,这个和线程启动无关,工夫上会略有出入。

退出移动版