hystrix三种降级策略,别离是:
- 熔断触发降级
- 超时触发降级
- 资源隔离触发降级,又分了线程池与信号量两种
上面联合示例别离介绍下。
一,熔断触发降级
1,当某个服务失败率达到肯定限度时将开启熔断器,这个服务后续再被调用时会被间接拒绝执行fallback逻辑(被调用方服务呈现了问题,调用方进行熔断)
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@EnableCircuitBreakerpublic 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的时候才熔断,这个和线程启动无关,工夫上会略有出入。