hystrix三种降级策略,即:断路器触发降级,超时触发降级资源隔离触发降级,分为线程池和信号量。下面分别介绍组合实例。一、熔断触发降级1、当某项服务的故障率达到一定限度时,熔断将被开启。后续调用此服务时,将直接拒绝执行fallback逻辑(被调用服务有问题,调用者进行熔断)2、熔断打开的两次条件请求数达到设定阈值。请求错误比例达到设定的阈值。3、例子/***HystrixProperty参数可以参考hystrixCommandProperties*Fuse触发降级*@return*10s以内(默认10s)当发起请求超过5次,失败率超过50%时,自动开启fuse。*从熔断开始到后续5s的请求都不会进入方法,并且*直接触发fallback回调方法返回。*/@GetMapping("/circuitBreaker/{num}")@HystrixCommand(commandProperties={//开启熔断功能@HystrixProperty(name="circuitBreaker.enabled",value="true"),//设置最小数量ofrequests@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="5"),//熔断时间5秒@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="5000"),//错误处理比例@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="50")},fallbackMethod="fallback")publicStringcircuitBreaker(@PathVariable("num")intnum){if(num%2==0){返回“正常访问”;}抛出新的RuntimeException("");}//进入参与请求方式输入的参数必须一致publicStringfallback(intnum){return"fusetriggerdowngrade";}打开保险丝开关@SpringBootApplication@EnableCircuitBreakerpublicclassApp{publicstaticvoidmain(String[]args){SpringApplication.run(App.class,args);}}本例中,当请求次数超过5次,也就是第6次时,如果错误率超过50%就会打开熔断器,进入回退逻辑,熔断器会在5秒内执行回退逻辑2开启熔断器后,超时会触发降级1,当某个服务的访问时间超过指定时间,可以认为该服务已经失败,不会继续等待,然后降级返回。2.Example/***超时触发降级*@return*/@GetMapping("/timeOut")@HystrixCommand(commandProperties={//开始超时触发降级@HystrixProperty(name="execution.timeout.enabled",value="true"),//超过1s触发降级@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1000"),},fallbackMethod="fallback")publicStringtimeOut()throwsInterruptedException{线程.睡眠(3000);返回“正常访问”;}publicStringfallback(){返回“触发降级”;}三、资源隔离触发降级1、资源隔离触发降级有两种:线程池和信号量,Hystrix默认使用线程池。我们先来看信号量。信号量是为了限制并发请求数。如果超过设定值,就会触发降级。信号量的特点是利用容器(如tomcat)的线程来处理请求,不涉及线程的上下切换。因为没有超时机制,适合不依赖外部服务的场景。publicStringfallback(){返回“触发降级”;}@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")publicStringsemaphore()throwsInterruptedException{return"semaphorenormalaccess";}再看线程池方法hystrix将需要隔离的资源或服务抽象形成一个command对象,然后使用设置好的和独立的线程池去执行,这样其他服务就不会受到影响。线程池隔离的一个特点是在容器(如tomcat)线程外创建了一个新的线程池,需要额外维护这个线程池,会有一定的开销(不过官方测试报告说开销不大)。私人整数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")publicvoidthread()抛出异常{Thread.sleep(1000);System.out.println(Thread.currentThread()+"正常访问"+num1++);}publicvoidfallback(){System.out.println("中断时间:"+newDate());}需要注意的是'超时时间'timeoutInMilliseconds,在例子中设置为3s,可能在第一次使用时才熔断4s,这与线程启动有关,时间会略有不同.
