熔断机制相当于电路的跳闸功能,即在一定时间内,错误比例达到一定数目时业务从原来流程转移到另外的流程处理。在一段时间后,恢复到原业务逻辑。

 

  测试代码如下

  

/**
 * @author zimu
 * @description Hystrix 熔断机制
 * @since 2018-3-1 16:20
 */
public class HystrixCommand4CircuitBreakerTest extends HystrixCommand < String > {

    private static final Logger log = LoggerFactory.getLogger(HystrixCommand4CircuitBreakerTest.class);

    private final String value;

    public HystrixCommand4CircuitBreakerTest(String value) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("CircuitBreakerTestGroup"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("CircuitBreakerTestKey"))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("CircuitBreakerTest"))
                .andThreadPoolPropertiesDefaults(    // 配置线程池
                        HystrixThreadPoolProperties.Setter()
                                .withCoreSize(200)    // 配置线程池里的线程数,设置足够多线程,以防未熔断却打满threadpool
                )
                .andCommandPropertiesDefaults(    // 配置熔断器
                        HystrixCommandProperties.Setter()
                                .withCircuitBreakerEnabled(true)
                                .withCircuitBreakerRequestVolumeThreshold(2)    //单位时间内最少请求次数
                                .withCircuitBreakerErrorThresholdPercentage(60)     //熔断比例
                                .withExecutionTimeoutInMilliseconds(500)   //单次执行超时时间
                                .withCircuitBreakerSleepWindowInMilliseconds(3000)      //熔断时间窗口,默认:5秒.熔断器中断请求5秒后会进入半打开状态,放下一个请求进来重试,如果该请求成功就关闭熔断器,否则继续等待一个熔断时间窗口
                )
        );
        this.value = value;
    }

    @Override
    protected String run() throws Exception {
        log.info("run():" + value);
        int num = Integer.valueOf(value);
        if (num % 2 == 0 && (num < 10 || num > 20)) {    // 直接返回
            return value;
        } else {
            TimeUnit.MILLISECONDS.sleep(800);
            return value;
        }
    }

    @Override
    protected String getFallback() {
        log.info("fallback: " + value);
        return "fallback: " + value;
    }

    public static class Test {

        public static void main(String[] args) {
            for (int i = 0; i < 30; i++) {
                try {
                    new HystrixCommand4CircuitBreakerTest(String.valueOf(i)).execute();

                    if (i > 15) {
                        TimeUnit.MILLISECONDS.sleep(1000);
                    }

                } catch (Exception e) {
                    System.out.println("HystrixBadRequestException" + e.getCause());
                }
            }

        }

    }

}

  

附:配置参数

//熔断器在整个统计时间内是否开启的阀值,默认20秒。也就是10秒钟内至少请求20次,熔断器才发挥起作用  
private final HystrixProperty<Integer> circuitBreakerRequestVolumeThreshold;   
//熔断器默认工作时间,默认:5秒.熔断器中断请求5秒后会进入半打开状态,放部分流量过去重试  
private final HystrixProperty<Integer> circuitBreakerSleepWindowInMilliseconds;   
//是否启用熔断器,默认true. 启动  
private final HystrixProperty<Boolean> circuitBreakerEnabled;   
//默认:50%。当出错率超过50%后熔断器启动.  
private final HystrixProperty<Integer> circuitBreakerErrorThresholdPercentage;  
//是否强制开启熔断器阻断所有请求,默认:false,不开启  
private final HystrixProperty<Boolean> circuitBreakerForceOpen;   
//是否允许熔断器忽略错误,默认false, 不开启  
private final HystrixProperty<Boolean> circuitBreakerForceClosed; 

  

//配置线程池大小,默认值10个. 建议值:请求高峰时99.5%的平均响应时间 + 向上预留一些即可 
 private final HystrixProperty corePoolSize; /*
 //配置线程值等待队列长度,默认值:-1 建议值:-1表示不等待直接拒绝,测试表明线程池使用直接决绝策略+ 合适大小的非回缩线程池效率最高.所以不建议修改此值。 当使用非回缩线程池时,queueSizeRejectionThreshold,keepAliveTimeMinutes 参数无效 
 private final HystrixProperty maxQueueSize;


 //请求合并是允许的最大请求数,默认:Integer.MAX_VALUE 
 private final HystrixProperty maxRequestsInBatch;  //批处理过程中每个命令延迟的时间,默认:10毫秒  private final HystrixProperty timerDelayInMilliseconds;  //批处理过程中是否开启请求缓存,默认:开启  private final HystrixProperty requestCacheEnabled;