使用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) {
// 最小配置,指定groupKey
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("helloWorldExceptionGroup")));
this.n = n;
}
@Override
protected 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 + "执行成功";
}
@Override
protected 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 zero
at 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()
/*