hystrix理解熔断和降级

hystrix 专栏收录该内容
2 篇文章 0 订阅

目录

降级(fallback)

熔断(circuit breaker)

 

降级(fallback)


MorningService

package hystrix.degrade;

/**
 * @Package Name : ${PACKAG_NAME}
 * @Author : 1766318593@qq.com
 * @Creation Date : 2019年04月03日上午11:20
 * @Function : todo
 */
public class MorningService {

    /**
     * 超时
     */
    public void timeout() {
        int j = 0;
        while (true) {
            j++;
        }
    }

    public static void main(String[] args) {

    }

}

HystrixFallbackTest.java

package hystrix.degrade;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;
import org.junit.Test;

import java.io.IOException;

/**
 * @Package Name : ${PACKAG_NAME}
 * @Author : 1766318593@qq.com
 * @Creation Date : 2019年04月03日上午11:21
 * @Function : todo
 */
public class HystrixFallbackTest extends HystrixCommand<String> {

    private final String name;

    private MorningService morningService;

    public HystrixFallbackTest(String name, MorningService morningService) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("FallbackGroup"))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(10000)));  // 10秒超时哦
        this.name = name;
        this.morningService = morningService;
    }

    @Override
    protected String run() throws Exception {
        /**
         * 超时触发fallback
         */
        morningService.timeout();
        return name;
    }

    /**
     * Hystrix的降级方法
     * @return
     */
    @Override
    protected String getFallback() {
        return "fallback: " + name;
    }

    public static class UnitTest {

        @Test
        public void testFallback() throws IOException {
            System.out.println(new HystrixFallbackTest("Morning", new MorningService()).execute());
        }
    }


}


执行上面的Test方法,在run方法里正常执行超过10秒就timeout了,走降级方法fallbck(),打印出的内容是:

fallback: Morning

降级就是在执行主流程时,主流程突然出现意外执行不下去了,那就执行另外一个方法让主流程看起来是正常的(这个方法通常就是降级方法,似乎有些牵强)。

熔断(circuit breaker)


保险丝:电路中正确安置保险丝,保险丝就会在电流异常升高到一定的高度和热度的时候,自身熔断切断电流,保护了电路安全运行。(来自百度百科)

熔断就跟保险丝一样,当一个服务请求并发特别大,服务器已经招架不住了,调用错误率飙升,当错误率达到一定阈值后,就将这个服务熔断了。熔断之后,后续的请求就不会再请求服务器了,以减缓服务器的压力。

来一个栗子吧: 
HystrixCircuitBreakerTest.java

代码块

package hystrix.circuitbreak;

import com.netflix.hystrix.*;
import hystrix.degrade.MorningService;
import org.junit.Test;

import java.io.IOException;

/**
 * @Package Name : ${PACKAG_NAME}
 * @Author : 1766318593@qq.com
 * @Creation Date : 2019年04月03日上午11:26
 * @Function : todo
 */
public class HystrixCircuitBreakerTest extends HystrixCommand<String> {

    private final String name;

    private MorningService morningService;

    public HystrixCircuitBreakerTest(String name, MorningService morningService) {
        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(3)    // 至少有3个请求才进行熔断错误比率计算
                                .withCircuitBreakerErrorThresholdPercentage(50)   //当出错率超过50%后熔断器启动
                                .withMetricsRollingStatisticalWindowInMilliseconds(5000)   // 统计滚动的时间窗口
                                .withCircuitBreakerSleepWindowInMilliseconds(200)   // 熔断器工作时间,超过这个时间,先放一个请求进去,成功的话就关闭熔断,失败就再等一段时间
                )
        );
        this.name = name;
        this.morningService = morningService;
    }

    @Override
    protected String run() throws Exception {
        int num = Integer.valueOf(name);
        if(num % 2 == 0) {  // 直接返回
            return name;
        } else {
            morningService.timeout(); // 无限循环模拟超时
        }
        return name;
    }


    /**
     * Whether or not your command has a fallback,
     * all of the usual Hystrix state and circuit-breaker state/metrics are updated to indicate the command failure.
     */
    @Override
    protected String getFallback() {
        return "CircuitBreaker fallback: " + name;
    }

    public static class UnitTest {

        @Test
        public void testSynchronous() throws IOException {
            for(int i = 0; i < 50; i++) {
                try {
                    System.out.println("===========" + new HystrixCircuitBreakerTest(String.valueOf(i), new MorningService()).execute());
                    // 查看熔断器是否打开
                    System.out.println("if circuit breaker open: " + HystrixCircuitBreaker.Factory.getInstance(HystrixCommandKey.Factory.asKey("CircuitBreakerTestKey")).isOpen());
                } catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


}


来看执行结果: 
1. 降级 


 
超时的请求走fallback
2. 熔断 


 
熔断器打开了,后续请求直接走降级方法fallback,不再调用主流程方法。 
3. 尝试恢复 


 
过了熔断器工作的时间窗以后,尝试放一个请求进去,执行成功就关闭熔断器,失败则继续打开,如此往复循环进行工作。

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值