分享

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

 liang1234_ 2020-02-13

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

  1. 非HystrixBadRequestException异常:当抛出HystrixBadRequestException时,调用程序可以捕获异常,此时不会触发fallback,而其他异常则会触发fallback,调用程序将获得fallback逻辑的返回结果。
  2. run()/construct()运行超时:执行命令的方法超时,将会触发fallback。
  3. 熔断器开启:当熔断器处于开启的状态,将会触发fallback。
  4. 线程池/信号量已满:当线程池/信号量已满的状态,将会触发fallback。

下面对这四种情况做简单的验证

  • 首先导入Maven依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

点击这里可查询最新的spring-cloud-starter-hystrix版本

  • 在主程序类中添加@EnableHystrix注解
package com.rambo.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.rambo.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.rambo.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.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand.run(HelloWorldExceptionCommand.java:29)
	at com.rambo.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.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 0-异常降级! C--> hystrix-helloWorldExceptionGroup-1
16:41:22.504 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 0执行失败
16:41:23.505 [hystrix-helloWorldExceptionGroup-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 1-HelloWorldExceptionCommand A--> hystrix-helloWorldExceptionGroup-2
16:41:23.505 [hystrix-helloWorldExceptionGroup-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 1-HelloWorldExceptionCommand B--> hystrix-helloWorldExceptionGroup-2
16:41:23.506 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 1执行成功
16:41:24.508 [hystrix-helloWorldExceptionGroup-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 2-HelloWorldExceptionCommand A--> hystrix-helloWorldExceptionGroup-3
16:41:24.508 [hystrix-helloWorldExceptionGroup-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 2-HelloWorldExceptionCommand B--> hystrix-helloWorldExceptionGroup-3
16:41:24.508 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 2执行成功
16:41:25.508 [hystrix-helloWorldExceptionGroup-4] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 0-HelloWorldExceptionCommand A--> hystrix-helloWorldExceptionGroup-4
16:41:25.508 [hystrix-helloWorldExceptionGroup-4] DEBUG com.netflix.hystrix.AbstractCommand - Error executing HystrixCommand.run(). Proceeding to fallback logic ...
java.lang.ArithmeticException: / by zero
	at com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand.run(HelloWorldExceptionCommand.java:29)
	at com.rambo.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:25.508 [hystrix-helloWorldExceptionGroup-4] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 0-异常降级! C--> hystrix-helloWorldExceptionGroup-4
16:41:25.509 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 0执行失败
16:41:26.511 [hystrix-helloWorldExceptionGroup-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 1-HelloWorldExceptionCommand A--> hystrix-helloWorldExceptionGroup-5
16:41:26.511 [hystrix-helloWorldExceptionGroup-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 1-HelloWorldExceptionCommand B--> hystrix-helloWorldExceptionGroup-5
16:41:26.511 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldExceptionCommand - 1执行成功

2、验证超时触发fallback

package com.rambo.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;
    }

    @Override
    protected 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 + "执行成功";
    }

    @Override
    protected 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);
            // 超时执行getFallback
            logger.info(command.execute());

            Thread.sleep(1000);
        }
    }
}

执行结果如下:

16:09:25.408 [hystrix-helloWorldTimeoutGroup-1] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-1
16:09:25.906 [HystrixTimer-1] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 超时降级! C--> HystrixTimer-1
16:09:25.913 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0执行失败
16:09:26.410 [hystrix-helloWorldTimeoutGroup-1] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-1
16:09:26.914 [hystrix-helloWorldTimeoutGroup-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-2
16:09:26.914 [hystrix-helloWorldTimeoutGroup-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-2
16:09:26.914 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1执行成功
16:09:27.915 [hystrix-helloWorldTimeoutGroup-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-3
16:09:27.915 [hystrix-helloWorldTimeoutGroup-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-3
16:09:27.915 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2执行成功
16:09:28.917 [hystrix-helloWorldTimeoutGroup-4] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-4
16:09:29.418 [HystrixTimer-1] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 超时降级! C--> HystrixTimer-1
16:09:29.419 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0执行失败
16:09:29.917 [hystrix-helloWorldTimeoutGroup-4] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-4
16:09:30.421 [hystrix-helloWorldTimeoutGroup-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-5
16:09:30.421 [hystrix-helloWorldTimeoutGroup-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-5
16:09:30.421 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1执行成功
16:09:31.423 [hystrix-helloWorldTimeoutGroup-6] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-6
16:09:31.423 [hystrix-helloWorldTimeoutGroup-6] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-6
16:09:31.423 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2执行成功
16:09:32.425 [hystrix-helloWorldTimeoutGroup-7] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-7
16:09:32.926 [HystrixTimer-4] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 超时降级! C--> HystrixTimer-4
16:09:32.926 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0执行失败
16:09:33.426 [hystrix-helloWorldTimeoutGroup-7] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-7
16:09:33.927 [hystrix-helloWorldTimeoutGroup-8] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-8
16:09:33.927 [hystrix-helloWorldTimeoutGroup-8] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-8
16:09:33.928 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1执行成功
16:09:34.929 [hystrix-helloWorldTimeoutGroup-9] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-9
16:09:34.929 [hystrix-helloWorldTimeoutGroup-9] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-9
16:09:34.929 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2执行成功
16:09:35.930 [hystrix-helloWorldTimeoutGroup-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-10
16:09:36.431 [HystrixTimer-3] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 超时降级! C--> HystrixTimer-3
16:09:36.432 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0执行失败
16:09:36.930 [hystrix-helloWorldTimeoutGroup-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 0-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-10
16:09:37.433 [hystrix-helloWorldTimeoutGroup-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-10
16:09:37.433 [hystrix-helloWorldTimeoutGroup-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-10
16:09:37.433 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 1执行成功
16:09:38.435 [hystrix-helloWorldTimeoutGroup-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2-HelloWorldTimeoutCommand A--> hystrix-helloWorldTimeoutGroup-10
16:09:38.435 [hystrix-helloWorldTimeoutGroup-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2-HelloWorldTimeoutCommand B--> hystrix-helloWorldTimeoutGroup-10
16:09:38.435 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldTimeoutCommand - 2执行成功

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

package com.rambo.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) {
        //最小配置,指定groupKey
        super(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;
    }

    @Override
    protected 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 + "执行成功";
    }

    @Override
    protected 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.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-1
16:35:36.190 [hystrix-helloWorldBreakerGroup-1] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-1
16:35:36.193 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0执行成功
16:35:36.194 [hystrix-helloWorldBreakerGroup-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-2
16:35:37.195 [hystrix-helloWorldBreakerGroup-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-2
16:35:37.201 [HystrixTimer-1] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-1
16:35:37.202 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1执行失败
16:35:37.203 [hystrix-helloWorldBreakerGroup-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-3
16:35:38.203 [hystrix-helloWorldBreakerGroup-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-3
16:35:38.203 [HystrixTimer-2] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-2
16:35:38.204 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2执行失败
16:35:38.205 [hystrix-helloWorldBreakerGroup-4] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 3-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-4
16:35:39.205 [HystrixTimer-1] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-1
16:35:39.205 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 3执行失败
16:35:39.206 [hystrix-helloWorldBreakerGroup-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 4-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-5
16:35:40.206 [hystrix-helloWorldBreakerGroup-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 4-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-5
16:35:40.206 [HystrixTimer-3] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-3
16:35:40.206 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 4执行失败
16:35:40.207 [hystrix-helloWorldBreakerGroup-6] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 5-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-6
16:35:41.207 [hystrix-helloWorldBreakerGroup-6] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 5-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-6
16:35:41.207 [HystrixTimer-2] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-2
16:35:41.208 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 5执行失败
16:35:41.209 [hystrix-helloWorldBreakerGroup-7] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 6-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-7
16:35:42.210 [hystrix-helloWorldBreakerGroup-7] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 6-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-7
16:35:42.211 [HystrixTimer-4] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-4
16:35:42.212 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 6执行失败
16:35:42.213 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:42.213 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 7执行失败
16:35:42.213 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:42.214 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 8执行失败
16:35:42.214 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:42.214 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 9执行失败
16:35:43.215 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.215 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0执行失败
16:35:43.215 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.215 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1执行失败
16:35:43.216 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.216 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2执行失败
16:35:43.216 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.216 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 3执行失败
16:35:43.216 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.216 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 4执行失败
16:35:43.216 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.216 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 5执行失败
16:35:43.216 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.216 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 6执行失败
16:35:43.216 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.216 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 7执行失败
16:35:43.217 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.217 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 8执行失败
16:35:43.217 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:43.217 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 9执行失败
16:35:44.218 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.218 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0执行失败
16:35:44.218 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.218 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1执行失败
16:35:44.218 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.218 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2执行失败
16:35:44.218 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.218 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 3执行失败
16:35:44.218 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.218 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 4执行失败
16:35:44.219 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.219 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 5执行失败
16:35:44.219 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.219 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 6执行失败
16:35:44.219 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.219 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 7执行失败
16:35:44.219 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.219 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 8执行失败
16:35:44.219 [main] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> main
16:35:44.219 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 9执行失败
16:35:45.220 [hystrix-helloWorldBreakerGroup-8] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-8
16:35:45.220 [hystrix-helloWorldBreakerGroup-8] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-8
16:35:45.225 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 0执行成功
16:35:45.226 [hystrix-helloWorldBreakerGroup-9] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-9
16:35:46.227 [hystrix-helloWorldBreakerGroup-9] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1-HelloWorldTimeoutCommand B--> hystrix-helloWorldBreakerGroup-9
16:35:46.227 [HystrixTimer-1] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-1
16:35:46.228 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 1执行失败
16:35:46.229 [hystrix-helloWorldBreakerGroup-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2-HelloWorldTimeoutCommand A--> hystrix-helloWorldBreakerGroup-10
16:35:47.229 [HystrixTimer-3] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 熔断降级! C--> HystrixTimer-3
16:35:47.230 [main] INFO com.rambo.hystrixtest.degrade.command.HelloWorldBreakerCommand - 2执行失败

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

package com.rambo.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;
    }

    @Override
    protected 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 + "执行完毕";
    }

    @Override
    protected String getFallback() {
        logger.error("线程池/信号量已满 FALLBACK --> !");
        return "FALLBACK";
    }

    public static class ThreadRunner extends Thread {
        private int i;

        public ThreadRunner(int i) {
            this.i = i;
        }

        @Override
        public 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.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 0-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-1
16:52:14.463 [hystrix-helloWorldThreadPool-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 1-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-2
16:52:14.964 [hystrix-helloWorldThreadPool-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 2-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-3
16:52:15.464 [hystrix-helloWorldThreadPool-4] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 3-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-4
16:52:15.965 [hystrix-helloWorldThreadPool-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 4-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-5
16:52:16.466 [hystrix-helloWorldThreadPool-6] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 5-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-6
16:52:16.966 [hystrix-helloWorldThreadPool-7] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 6-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-7
16:52:17.466 [hystrix-helloWorldThreadPool-8] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 7-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-8
16:52:17.967 [hystrix-helloWorldThreadPool-9] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 8-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-9
16:52:18.466 [hystrix-helloWorldThreadPool-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 9-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-10
16:52:18.970 [Thread-10] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:18.973 [Thread-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:19.466 [Thread-11] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:19.467 [Thread-11] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:19.967 [Thread-12] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:19.967 [Thread-12] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:20.468 [Thread-13] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:20.468 [Thread-13] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:20.968 [Thread-14] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:20.968 [Thread-14] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:21.469 [Thread-15] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:21.469 [Thread-15] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:21.970 [Thread-16] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:21.970 [Thread-16] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:22.469 [Thread-17] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:22.469 [Thread-17] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:22.970 [Thread-18] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:22.971 [Thread-18] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:23.471 [Thread-19] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:23.472 [Thread-19] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:23.972 [Thread-20] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:23.972 [Thread-20] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:24.405 [hystrix-helloWorldThreadPool-1] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 0-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-1
16:52:24.406 [Thread-0] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 0执行完毕
16:52:24.464 [hystrix-helloWorldThreadPool-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 1-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-2
16:52:24.464 [Thread-1] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 1执行完毕
16:52:24.472 [Thread-21] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:24.473 [Thread-21] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:24.964 [hystrix-helloWorldThreadPool-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 2-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-3
16:52:24.964 [Thread-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 2执行完毕
16:52:24.973 [Thread-22] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:24.973 [Thread-22] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:25.465 [hystrix-helloWorldThreadPool-4] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 3-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-4
16:52:25.465 [Thread-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 3执行完毕
16:52:25.473 [Thread-23] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:25.473 [Thread-23] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:25.966 [hystrix-helloWorldThreadPool-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 4-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-5
16:52:25.966 [Thread-4] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 4执行完毕
16:52:25.975 [Thread-24] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:25.975 [Thread-24] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:26.466 [hystrix-helloWorldThreadPool-6] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 5-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-6
16:52:26.466 [Thread-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 5执行完毕
16:52:26.475 [hystrix-helloWorldThreadPool-6] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 25-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-6
16:52:26.967 [hystrix-helloWorldThreadPool-7] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 6-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-7
16:52:26.973 [Thread-6] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 6执行完毕
16:52:26.976 [hystrix-helloWorldThreadPool-7] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 26-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-7
16:52:27.466 [hystrix-helloWorldThreadPool-8] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 7-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-8
16:52:27.466 [Thread-7] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 7执行完毕
16:52:27.476 [hystrix-helloWorldThreadPool-8] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 27-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-8
16:52:27.967 [hystrix-helloWorldThreadPool-9] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 8-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-9
16:52:27.967 [Thread-8] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 8执行完毕
16:52:27.977 [hystrix-helloWorldThreadPool-9] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 28-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-9
16:52:28.467 [hystrix-helloWorldThreadPool-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 9-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-10
16:52:28.467 [Thread-9] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 9执行完毕
16:52:28.477 [hystrix-helloWorldThreadPool-10] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 29-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-10
16:52:28.977 [hystrix-helloWorldThreadPool-5] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 30-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-5
16:52:29.478 [hystrix-helloWorldThreadPool-4] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 31-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-4
16:52:29.978 [hystrix-helloWorldThreadPool-3] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 32-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-3
16:52:30.479 [hystrix-helloWorldThreadPool-2] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 33-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-2
16:52:30.979 [hystrix-helloWorldThreadPool-1] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 34-HelloWorldThreadPoolCommand A--> hystrix-helloWorldThreadPool-1
16:52:31.479 [Thread-35] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:31.480 [Thread-35] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:31.980 [Thread-36] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:31.981 [Thread-36] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:32.481 [Thread-37] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:32.481 [Thread-37] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:32.981 [Thread-38] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:32.981 [Thread-38] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:33.482 [Thread-39] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:33.482 [Thread-39] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:33.982 [Thread-40] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:33.983 [Thread-40] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:34.482 [Thread-41] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:34.482 [Thread-41] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:34.983 [Thread-42] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:34.983 [Thread-42] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:35.483 [Thread-43] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:35.483 [Thread-43] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:35.984 [Thread-44] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:35.984 [Thread-44] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK
16:52:36.475 [hystrix-helloWorldThreadPool-6] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 25-HelloWorldThreadPoolCommand B--> hystrix-helloWorldThreadPool-6
16:52:36.475 [Thread-25] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 25执行完毕
16:52:36.484 [Thread-45] ERROR com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - 线程池/信号量已满 FALLBACK --> !
16:52:36.484 [Thread-45] INFO com.rambo.hystrixtest.degrade.command.HelloWorldThreadPoolCommand - FALLBACK

以上结果均符合预期

– END –

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多