使用Hystrix时,下面的情况会触发fallback:

非HystrixBadRequestException异常:当抛出HystrixBadRequestException时,调用程序可以捕获异常,此时不会触发fallback,而其他异常则会触发fallback,调用程序将获得fallback逻辑的返回结果。
run()/construct()运行超时:执行命令的方法超时,将会触发fallback。
熔断器开启:当熔断器处于开启的状态,将会触发fallback。
线程池/信号量已满:当线程池/信号量已满的状态,将会触发fallback。
下面对这四种情况做简单的验证
首先导入Maven依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version>
</dependency>

在主程序类中添加@EnableHystrix注解

package com.hlh.hystrixtest;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;@SpringBootApplication
@EnableHystrix
public class HystrixtestApplication {public static void main(String[] args) {SpringApplication.run(HystrixtestApplication.class, args);}
}

1、验证异常触发fallback

package com.hlh.hystrixtest.degrade.command;import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 异常降级* 非HystrixBadRequestException异常:当抛出HystrixBadRequestException时,* 调用程序可以捕获异常,此时不会触发fallback,而其他异常则会触发fallback,* 调用程序将获得fallback逻辑的返回结果。*/
public class HelloWorldExceptionCommand extends HystrixCommand<String> {private final static Logger logger = LoggerFactory.getLogger(HelloWorldExceptionCommand.class);private final int n;public HelloWorldExceptionCommand(int n) {// 最小配置,指定groupKeysuper(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("helloWorldExceptionGroup")));this.n = n;}@Overrideprotected String run() throws Exception {logger.info(n + "-HelloWorldExceptionCommand A--> " + Thread.currentThread().getName());// 制造异常int i = 1 / n;// 如果此处异常被捕获,将不会进入getFallback()/*try {int i = 1 / n;} catch (Exception e) {logger.error("异常:" + e.getMessage());}*/logger.info(n + "-HelloWorldExceptionCommand B--> " + Thread.currentThread().getName());return n + "执行成功";}@Overrideprotected String getFallback() {logger.error(n + "-异常降级! C--> " + Thread.currentThread().getName());return n + "执行失败";}public static void main(String[] args) throws Exception {for (int i = 0; i < Integer.MAX_VALUE; i++) {if (i == 3) {i = 0;}HelloWorldExceptionCommand command = new HelloWorldExceptionCommand(i);logger.info(command.execute());Thread.sleep(1000);}}
}

执行结果如下:

16:41:22.493 [hystrix-helloWorldExceptionGroup-1] INFO com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand - 0-HelloWorldExceptionCommand A--> hystrix-helloWorldExceptionGroup-1
16:41:22.496 [hystrix-helloWorldExceptionGroup-1] DEBUG com.netflix.hystrix.AbstractCommand - Error executing HystrixCommand.run(). Proceeding to fallback logic ...
java.lang.ArithmeticException: / by zeroat com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand.run(HelloWorldExceptionCommand.java:29)at com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand.run(HelloWorldExceptionCommand.java:14)at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302)at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298)at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)at rx.Observable.unsafeSubscribe(Observable.java:10327)at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)at rx.Observable.unsafeSubscribe(Observable.java:10327)at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)at rx.Observable.unsafeSubscribe(Observable.java:10327)at rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100)at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.java:56)at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.java:47)at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction.call(HystrixContexSchedulerAction.java:69)at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)
16:41:22.500 [hystrix-helloWorldExceptionGroup-1] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand - 0-异常降级! C--> hystrix-helloWorldExceptionGroup-1
16:41:22.504 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand - 0执行失败
16:41:23.505 [hystrix-helloWorldExceptionGroup-2] INFO com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand - 1-HelloWorldExceptionCommand A--> hystrix-helloWorldExceptionGroup-2
16:41:23.505 [hystrix-helloWorldExceptionGroup-2] INFO com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand - 1-HelloWorldExceptionCommand B--> hystrix-helloWorldExceptionGroup-2
16:41:23.506 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand - 1执行成功
16:41:24.508 [hystrix-helloWorldExceptionGroup-3] INFO com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand - 2-HelloWorldExceptionCommand A--> hystrix-helloWorldExceptionGroup-3
16:41:24.508 [hystrix-helloWorldExceptionGroup-3] INFO com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand - 2-HelloWorldExceptionCommand B--> hystrix-helloWorldExceptionGroup-3
16:41:24.508 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldExceptionCommand - 2执行成功

2、验证超时触发fallback

package com.hlh.hystrixtest.degrade.command;import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 超时降级* **run()/construct()运行超时:执行命令的方法超时,将会触发fallback。*/
public class HelloWorldTimeoutCommand extends HystrixCommand<String> {private final static Logger logger = LoggerFactory.getLogger(HelloWorldTimeoutCommand.class);private final int n;public HelloWorldTimeoutCommand(int n) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("helloWorldTimeoutGroup")).andCommandPropertiesDefaults(HystrixCommandProperties.Setter()/** execution.isolation.thread.timeoutInMilliseconds* 设置调用者等待命令执行的超时限制,超过此时间,HystrixCommand被标记为TIMEOUT,* 并执行回退逻辑。* 默认值:1000(毫秒)*/.withExecutionTimeoutInMilliseconds(500)/** execution.timeout.enabled* 设置HystrixCommand的执行是否有超时限制。* 默认值:true*/.withExecutionTimeoutEnabled(true)/** execution.isolation.thread.interruptOnTimeout* 设置HystrixCommand的执行是否在超时发生时被中断。* 使用线程隔离时,是否对命令执行超时的线程调用中断(Thread.interrupt())操作。* 默认值:true*/.withExecutionIsolationThreadInterruptOnTimeout(false)));this.n = n;}@Overrideprotected String run() throws Exception {logger.info(n + "-HelloWorldTimeoutCommand A--> " + Thread.currentThread().getName());if (n == 0) {// 设置超时Thread.sleep(1000);}// 设置withExecutionIsolationThreadInterruptOnTimeout(false)后面代码将会继续执行logger.info(n + "-HelloWorldTimeoutCommand B--> " + Thread.currentThread().getName());return n + "执行成功";}@Overrideprotected String getFallback() {logger.error("超时降级! C--> " + Thread.currentThread().getName());return n + "执行失败";}public static void main(String[] args) throws Exception {for (int i = 0; i < Integer.MAX_VALUE; i++) {if (i == 5) {i = 0;}HelloWorldTimeoutCommand command = new HelloWorldTimeoutCommand(i);// 超时执行getFallbacklogger.info(command.execute());Thread.sleep(1000);}}
}

执行结果如下:

16:09:25.408 [hystrix-helloWorldTimeoutGroup-1] INFO com.hlh.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-1
16:09:25.906 [HystrixTimer-1] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 超时降级! C--> HystrixTimer-1
16:09:25.913 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0执行失败
16:09:26.410 [hystrix-helloWorldTimeoutGroup-1] INFO com.hlh.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-1
16:09:26.914 [hystrix-helloWorldTimeoutGroup-2] INFO com.hlh.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-2
16:09:26.914 [hystrix-helloWorldTimeoutGroup-2] INFO com.hlh.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-2
16:09:26.914 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1执行成功

3、验证熔断器开启触发fallback

package com.hlh.hystrixtest.degrade.command;import com.netflix.hystrix.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 触发熔断器熔断* **熔断器开启:当熔断器处于开启的状态,将会触发fallback。*/
public class HelloWorldBreakerCommand extends HystrixCommand<String> {private final static Logger logger = LoggerFactory.getLogger(HelloWorldBreakerCommand.class);private final int n;public HelloWorldBreakerCommand(int n) {//最小配置,指定groupKeysuper(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("helloWorldBreakerGroup")).andCommandPropertiesDefaults(HystrixCommandProperties.Setter()/** execution.isolation.thread.timeoutInMilliseconds* 设置调用者等待命令执行的超时限制,超过此时间,HystrixCommand被标记为TIMEOUT,* 并执行回退逻辑。* 默认值:1000(毫秒)*/.withExecutionTimeoutInMilliseconds(1000)/** execution.isolation.thread.interruptOnTimeout* 设置HystrixCommand的执行是否在超时发生时被中断。* 使用线程隔离时,是否对命令执行超时的线程调用中断(Thread.interrupt())操作。* 默认值:true*/.withExecutionIsolationThreadInterruptOnTimeout(true)// ** 断路器(Circuit Breaker)属性配置 **/** circuitBreaker.enabled* 设置断路器是否生效* 默认值:true*/.withCircuitBreakerEnabled(true)/** circuitBreaker.requestVolumeThreshold* 设置在一个滚动窗口中,打开断路器的最少请求数。比如:如果值是20,在一个窗口内(比如10秒),收到19个请求,即使这19个请求都失败了,断路器也不会打开。* 默认值:20*/.withCircuitBreakerRequestVolumeThreshold(6)/** circuitBreaker.sleepWindowInMilliseconds* 设置在断路器被打开,拒绝请求到再次尝试请求的时间间隔。* 默认值:5000(毫秒)*/.withCircuitBreakerSleepWindowInMilliseconds(3000)/** circuitBreaker.errorThresholdPercentage* 设置打开断路器并启动回退逻辑的错误比率。* (这个参数的效果受到circuitBreaker.requestVolumeThreshold和滚动时间窗口的时间长度影响)* 默认值:50(%)*/.withCircuitBreakerErrorThresholdPercentage(50))//设置核心线程池的大小.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(20)));this.n = n;}@Overrideprotected String run() throws Exception {logger.info(n + "-HelloWorldTimeoutCommand A--> " + Thread.currentThread().getName());if (n > 0) {// 设置超时Thread.sleep(1000);}// 设置withExecutionIsolationThreadInterruptOnTimeout(true)后面代码将中断执行logger.info(n + "-HelloWorldTimeoutCommand B--> " + Thread.currentThread().getName());return n + "执行成功";}@Overrideprotected String getFallback() {logger.error("熔断降级! C--> " + Thread.currentThread().getName());return n + "执行失败";}public static void main(String[] args) throws Exception {for (int i = 0; i < Integer.MAX_VALUE; i++) {try {if (i == 10) {i = 0;Thread.sleep(1000);}logger.info(new HelloWorldBreakerCommand(i).execute());} catch (Exception e) {logger.error("异常:" + e.getMessage(), e);}}}
}

执行结果如下:

16:35:36.190 [hystrix-helloWorldBreakerGroup-1] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-1
16:35:36.190 [hystrix-helloWorldBreakerGroup-1] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-1
16:35:36.193 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0执行成功
16:35:36.194 [hystrix-helloWorldBreakerGroup-2] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-2
16:35:37.195 [hystrix-helloWorldBreakerGroup-2] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-2
16:35:37.201 [HystrixTimer-1] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-1
16:35:37.202 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1执行失败
16:35:37.203 [hystrix-helloWorldBreakerGroup-3] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-3
16:35:38.203 [hystrix-helloWorldBreakerGroup-3] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-3
16:35:38.203 [HystrixTimer-2] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-2
16:35:38.204 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2执行失败
16:35:38.205 [hystrix-helloWorldBreakerGroup-4] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 3-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-4
16:35:39.205 [HystrixTimer-1] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-1
16:35:39.205 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 3执行失败
16:35:39.206 [hystrix-helloWorldBreakerGroup-5] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 4-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-5
16:35:40.206 [hystrix-helloWorldBreakerGroup-5] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 4-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-5
16:35:40.206 [HystrixTimer-3] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-3
16:35:40.206 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 4执行失败
16:35:40.207 [hystrix-helloWorldBreakerGroup-6] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 5-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-6
16:35:41.207 [hystrix-helloWorldBreakerGroup-6] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 5-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-6
16:35:41.207 [HystrixTimer-2] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-2
16:35:41.208 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 5执行失败
16:35:41.209 [hystrix-helloWorldBreakerGroup-7] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 6-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-7
16:35:42.210 [hystrix-helloWorldBreakerGroup-7] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 6-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-7
16:35:42.211 [HystrixTimer-4] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-4
16:35:42.212 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 6执行失败
16:35:42.213 [main] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:42.213 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 7执行失败
16:35:42.213 [main] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:42.214 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 8执行失败
16:35:42.214 [main] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:42.214 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 9执行失败
16:35:43.215 [main] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.215 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0执行失败
16:35:43.215 [main] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.215 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1执行失败
16:35:43.216 [main] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.216 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2执行失败
16:35:43.216 [main] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.216 [main] INFO com.hlh.hystrixtest.degrade.command.HelloWorldBreakerCommand - 3执行失败

4、验证线程池/信号量已满触发fallback

package com.hlh.hystrixtest.degrade.command;import com.netflix.hystrix.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 线程池/信号量已满* **当线程池/信号量已满的状态,将会触发fallback。*/
public class HelloWorldThreadPoolCommand extends HystrixCommand<String> {private final static Logger logger = LoggerFactory.getLogger(HelloWorldThreadPoolCommand.class);private final int n;public HelloWorldThreadPoolCommand(int n) {super(Setter// *** 基础属性配置 ***/** CommandGroup是每个命令最少配置的必选参数,在不指定ThreadPoolKey的情况下,* 字面值用于对不同依赖的线程池/信号区分,也就是在不指定ThreadPoolKey的情况下,* CommandGroup用于指定线程池的隔离。命令分组用于对依赖操作分组,便于统计、汇总等。*/.withGroupKey(HystrixCommandGroupKey.Factory.asKey("helloWorldThreadPoolGroup"))/** CommandKey是作为依赖命名,一般来说每个CommandKey代表一个依赖抽象,* 相同的依赖要使用相同的CommandKey名称。依赖隔离的根本就是对相同CommandKey的依赖做隔离。* 不同的依赖隔离最好使用不同的线程池(定义不同的ThreadPoolKey)。* 从HystrixCommand源码的注释也可以看到CommandKey也用于对依赖操作统计、汇总等。*/.andCommandKey(HystrixCommandKey.Factory.asKey("helloWorldThreadPoolCommand"))/** ThreadPoolKey简单来说就是依赖隔离使用的线程池的键值。* 当对同一业务依赖做隔离时使用CommandGroup做区分,* 但是对同一依赖的不同远程调用如(一个是redis 一个是http),可以使用HystrixThreadPoolKey做隔离区分。* 虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用HystrixThreadPoolKey区分。* (对于每个不同的HystrixThreadPoolKey建议使用不同的CommandKey)*/.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("helloWorldThreadPool"))// *** 设置命令属性配置默认值 ***.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()// ** 执行属性 **/** execution.isolation.strategy* 用于设置HystrixCommand执行的隔离策略,有两种选项:* THREAD —— 在固定大小线程池中,以单独线程执行,并发请求数受限于线程池大小。* SEMAPHORE —— 在调用线程中执行,通过信号量来限制并发量。* 默认值:THREAD(ExecutionIsolationStrategy.THREAD)可选值:THREAD,SEMAPHORE*/.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)/** execution.isolation.thread.timeoutInMilliseconds* 设置调用者等待命令执行的超时限制,超过此时间,HystrixCommand被标记为TIMEOUT,* 并执行回退逻辑。* 默认值:1000(毫秒)*/.withExecutionTimeoutInMilliseconds(1000)/** execution.timeout.enabled* 设置HystrixCommand的执行是否有超时限制。* 默认值:true*/.withExecutionTimeoutEnabled(false)/** execution.isolation.thread.interruptOnTimeout* 设置HystrixCommand的执行是否在超时发生时被中断。* 使用线程隔离时,是否对命令执行超时的线程调用中断(Thread.interrupt())操作。* 默认值:true*/.withExecutionIsolationThreadInterruptOnTimeout(true)/** execution.isolation.semaphore.maxConcurrentRequests* 设置当使用ExecutionIsolationStrategy.SEMAPHORE时,HystrixCommand执行方法允许的最大请求数。* 如果达到最大并发数时,后续请求会被拒绝。* 信号量应该是容器(比如Tomcat)线程池一小部分,不能等于或者略小于容器线程池大小,否则起不到保护作用。* 默认值:10*/.withExecutionIsolationSemaphoreMaxConcurrentRequests(10)// ** 回退属性 **// 下面的属性控制HystrixCommand.getFallback()执行。// 这些属性对ExecutionIsolationStrategy.THREAD和ExecutionIsolationStrategy.SEMAPHORE都有效。/** fallback.isolation.semaphore.maxConcurrentRequests* 设置调用线程产生的HystrixCommand.getFallback()方法的允许最大请求数目。* 如果达到最大并发数目,后续请求将会被拒绝,如果没有实现回退,则抛出异常。* (这里需要注意一点,这个变量的命名不是很规范,它实际上对THREAD和SEMAPHORE两种隔离策略都生效)* 默认值:10*/.withFallbackIsolationSemaphoreMaxConcurrentRequests(10)/** fallback.enabled* 该属性决定当前的调用故障或者拒绝发生时,是否调用HystrixCommand.getFallback()。* 默认值:true*/.withFallbackEnabled(true)// ** 断路器(Circuit Breaker)属性配置 **/** circuitBreaker.enabled* 设置断路器是否生效* 默认值:true*/.withCircuitBreakerEnabled(true)/** circuitBreaker.requestVolumeThreshold* 设置在一个滚动窗口中,打开断路器的最少请求数。比如:如果值是20,在一个窗口内(比如10秒),收到19个请求,即使这19个请求都失败了,断路器也不会打开。* 默认值:20*/.withCircuitBreakerRequestVolumeThreshold(5)/** circuitBreaker.sleepWindowInMilliseconds* 设置在断路器被打开,拒绝请求到再次尝试请求的时间间隔。* 默认值:5000(毫秒)*/.withCircuitBreakerSleepWindowInMilliseconds(5000)/** circuitBreaker.errorThresholdPercentage* 设置打开断路器并启动回退逻辑的错误比率。* (这个参数的效果受到circuitBreaker.requestVolumeThreshold和滚动时间窗口的时间长度影响)* 默认值:50(%)*/.withCircuitBreakerErrorThresholdPercentage(50)/** circuitBreaker.forceOpen* 如果该属性设置为true,强制断路器进入打开状态,将会拒绝所有的请求。* 该属性优先级比circuitBreaker.forceClosed高* 默认值:false*/.withCircuitBreakerForceOpen(false)/** circuitBreaker.forceClosed* 如果该属性设置为true,强制断路器进入关闭状态,将会允许所有的请求,无视错误率。* 默认值:false*/.withCircuitBreakerForceClosed(false)// ** 请求上下文属性配置 **/** requestCache.enabled* 设置HystrixCommand.getCacheKey()是否启用,由HystrixRequestCache通过请求缓存提供去重复数据功能。* (请求结果缓存需要配合HystrixRequestContext使用,具体应用可以自行查阅)* 默认值:true*/.withRequestCacheEnabled(true)/** requestLog.enabled* 设置HystrixCommand执行和事件是否要记录日志到HystrixRequestLog。* 默认值:true*/.withRequestLogEnabled(true))// *** 设置线程池属性配置默认值 ***.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()/** coreSize* 设置核心线程池的大小(这个值和ThreadPoolExecutor的coreSize的含义不一样)* 默认值:10*/.withCoreSize(10)/** maximumSize* 1.5.9新增属性,设置线程池最大值。* 这个是在不开始拒绝HystrixCommand的情况下支持的最大并发数。* 这个属性起作用的前提是设置了allowMaximumSizeToDivergeFromCoreSize。* 1.5.9之前,核心线程池大小和最大线程池大小总是相同的。* 默认值:10*/.withMaximumSize(10)/** maxQueueSize* 设置BlockingQueue最大的队列值。如果设置为-1,* 那么使用SynchronousQueue,否则正数将会使用LinkedBlockingQueue。* 如果需要去除这些限制,允许队列动态变化,可以参考queueSizeRejectionThreshold属性。* 修改SynchronousQueue和LinkedBlockingQueue需要重启。* 默认值:-1*/.withMaxQueueSize(-1)/** queueSizeRejectionThreshold* 设置队列拒绝的阈值—-一个人为设置的拒绝访问的最大队列值,即使当前队列元素还没达到maxQueueSize。* 当将一个线程放入队列等待执行时,HystrixCommand使用该属性。* 注意:如果maxQueueSize设置为-1,该属性不可用。* 默认值:5*/.withQueueSizeRejectionThreshold(5)/** keepAliveTimeMinutes* 设置存活时间,单位分钟。如果coreSize小于maximumSize,那么该属性控制一个线程从实用完成到被释放的时间。* 默认值:1*/.withKeepAliveTimeMinutes(1)/** allowMaximumSizeToDivergeFromCoreSize* 在1.5.9中新增的属性。该属性允许maximumSize起作用。属性值可以等于或者大于coreSize值,* 设置coreSize小于maximumSize的线程池能够支持maximumSize的并发数,* 但是会将不活跃的线程返回到系统中去。* 默认值:false*/.withAllowMaximumSizeToDivergeFromCoreSize(false)/** metrics.rollingStats.timeInMilliseconds* 设置统计的滚动窗口的时间段大小。该属性是线程池保持指标时间长短。* 默认值:10000(毫秒)*/.withMetricsRollingStatisticalWindowInMilliseconds(10000)/** metrics.rollingStats.numBuckets* 设置滚动的统计窗口被分成的桶(bucket)的数目。* 注意:”metrics.rollingStats.timeInMilliseconds % metrics.rollingStats.numBuckets == 0”必须为true,否则会抛出异常。* 默认值:10*/.withMetricsRollingStatisticalWindowBuckets(10)));this.n = n;}@Overrideprotected String run() throws Exception {logger.info(n + "-HelloWorldThreadPoolCommand A--> " + Thread.currentThread().getName());Thread.sleep(10000);logger.info(n + "-HelloWorldThreadPoolCommand B--> " + Thread.currentThread().getName());return n + "执行完毕";}@Overrideprotected String getFallback() {logger.error("线程池/信号量已满 FALLBACK --> !");return "FALLBACK";}public static class ThreadRunner extends Thread {private int i;public ThreadRunner(int i) {this.i = i;}@Overridepublic void run() {logger.info(new HelloWorldThreadPoolCommand(i).execute());}}public static void main(String[] args) throws Exception {// 关闭HystrixCommand执行的超时限制,设置withExecutionTimeoutEnabled(false)// withCoreSize(10)for (int i = 0; i < Integer.MAX_VALUE; i++) {Thread thread = new ThreadRunner(i);thread.start();Thread.sleep(500);}}
}

执行结果如下:

16:52:14.404 [hystrix-helloWorldThreadPool-1] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 0-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-1
16:52:14.463 [hystrix-helloWorldThreadPool-2] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 1-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-2
16:52:14.964 [hystrix-helloWorldThreadPool-3] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 2-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-3
16:52:15.464 [hystrix-helloWorldThreadPool-4] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 3-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-4
16:52:15.965 [hystrix-helloWorldThreadPool-5] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 4-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-5
16:52:16.466 [hystrix-helloWorldThreadPool-6] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 5-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-6
16:52:16.966 [hystrix-helloWorldThreadPool-7] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 6-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-7
16:52:17.466 [hystrix-helloWorldThreadPool-8] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 7-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-8
16:52:17.967 [hystrix-helloWorldThreadPool-9] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 8-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-9
16:52:18.466 [hystrix-helloWorldThreadPool-10] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 9-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-10
16:52:18.970 [Thread-10] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:18.973 [Thread-10] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:19.466 [Thread-11] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:19.467 [Thread-11] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:19.967 [Thread-12] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:19.967 [Thread-12] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:20.468 [Thread-13] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:20.468 [Thread-13] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:20.968 [Thread-14] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:20.968 [Thread-14] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:21.469 [Thread-15] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:21.469 [Thread-15] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:21.970 [Thread-16] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:21.970 [Thread-16] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:22.469 [Thread-17] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:22.469 [Thread-17] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:22.970 [Thread-18] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:22.971 [Thread-18] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:23.471 [Thread-19] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:23.472 [Thread-19] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:23.972 [Thread-20] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:23.972 [Thread-20] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:24.405 [hystrix-helloWorldThreadPool-1] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 0-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-1
16:52:24.406 [Thread-0] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 0执行完毕
16:52:24.464 [hystrix-helloWorldThreadPool-2] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 1-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-2
16:52:24.464 [Thread-1] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 1执行完毕
16:52:24.472 [Thread-21] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:24.473 [Thread-21] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:24.964 [hystrix-helloWorldThreadPool-3] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 2-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-3
16:52:24.964 [Thread-2] INFO com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 2执行完毕
16:52:24.973 [Thread-22] ERROR com.hlh.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !

结束!

Hystrix之四种触发fallback情况相关推荐

  1. Hystrix之四种触发fallback情况的验证

    使用Hystrix时,下面的情况会触发fallback: 非HystrixBadRequestException异常:当抛出HystrixBadRequestException时,调用程序可以捕获异常 ...

  2. 示波器的三种触发模式详解

    一.什么是示波器的触发模式? 示波器的"触发"就是使得示波器的扫描与被观测信号同步,从而显示稳定的波形.为满足不同的观测需要,需要不同的"触发模式".示波器的基 ...

  3. Python无法加载vc产生的DLL - 一种异常的情况

    Python无法加载vc产生的DLL - 一种异常的情况 本地调试时候一切正常,发布给客户就出现如下错误:无法导入DLL. 最后查明原因是:VC编译dll的设定差异导致. 有问题的设置: 改变后的设置 ...

  4. EDIUS激活停用遇这五种报错情况,该如何解决?

    EDIUS激活停用遇这五种报错情况,该如何解决? EDIUS是一款专业的非线性视频编辑软件,专为广播和后期制作环境而设计.但是初次使用该软件的用户,可能会遇到一些问题.v:t-13-52-01-24- ...

  5. 口袋中有红、黄、蓝、白、黑5种颜色的球若干个,每次从口袋中先后取出3个球,问得到3种不同颜色的球的可能取法,输出每种排列的情况。

    口袋中有红.黄.蓝.白.黑5种颜色的球若干个,每次从口袋中先后取出3个球,问得到3种不同颜色的球的可能取法,输出每种排列的情况. 方法:(枚举) #include<stdio.h>int ...

  6. 【C】例9.12口袋中有红、黄、蓝、白、黑5种颜色的球若干。每次从口袋中先后取出3个球, 问得到3种不同颜色的球的可能取法,输出每种排列的情况

    //口袋中有红.黄.蓝.白.黑5种颜色的球若干.每次从口袋中先后取出3个球, //问得到3种不同颜色的球的可能取法,输出每种排列的情况 #include <stdio.h> int mai ...

  7. python之四种方式读取文档

    python之四种方式读取文档 第一种:读取纯文本 1:代码 # coding=utf-8 """ @author: jiajiknag 程序功能: 读取txt文件 &q ...

  8. 有两种常见的情况充斥着SEO优化市场,让排名得不到稳定

    成都SEO:随着这一段百度大调整的到来,新一轮的排名下降越演越烈,本来昨天还在前两页,但说不今天就已经是百里之外了.成都SEO经过研究得知,其实掉到100以外为严重降权,掉到3-40名为有一些失误导致 ...

  9. html之四种方法导入css...

    原文地址:http://hi.baidu.com/lizhanfu/blog/item/4dbc806499bed82fab184c9c.html 在html中,引入css的方法主要有行内式.内嵌式. ...

最新文章

  1. /etc/inittab
  2. python语言可以应用在哪些方面-python应用于哪些方面
  3. 快速深入一门语言的几个问题 - Shell909090 - 随笔杂记
  4. redis设置为前台运行的方式
  5. esri geometry-api-java的maven创建
  6. idea2020.03 lombok异常
  7. MIT 18.03 写给初学者的微积分校对活动 | ApacheCN
  8. linux安装启动svn
  9. HTML特殊字符转义
  10. Java 运行环境安装(JRE JDK 区别)
  11. wps excel 插入公式 整列
  12. 计算机量子化学计算实验报告物化实验,化学反应焓变的量子化学理论计算实验报告.doc...
  13. linux用户管理(1)----创建用户(adduser和useradd)和删除用户(userdel)
  14. oracle omf管理,论OMF管理文件的重要性
  15. python read()读取图片_可以python sitk.ReadImage读取列表/系列图像吗?
  16. 电子商务计算机考研学校排名,电子商务考研院校排名
  17. OSChina 周二乱弹 —— 你一辈子都不可能跟她这么亲近
  18. python中如何将数字转换成中文数字_Python把数字变成中文的方法
  19. 网络知识 ACL NAT IPv6
  20. python如果否则_Python传递参数(如果已定义),否则使用defau

热门文章

  1. BT种子破案,FBI可以,你也行
  2. 关于Clipper库使用小结
  3. PC休闲游戏~植物大战僵尸-植物连连看v1.0正式发布啦(更新iPhone版本)!
  4. Android内核三大核心功能之一AMS内部原理
  5. 【Python练习】创建学生信息表-列表推导式的应用
  6. 苹果cookie是打开还是关闭_cookie那些事
  7. xaut 循环结构习题 公式求兀值
  8. STC51单片机数码管显示程序和仿真
  9. 使用Masonry布局后不能立即获取到frame
  10. iis 设置网站前台后台 http和https分离访问