Hystrix 熔断降级配置

1. 基础知识

1.1 服务隔离

img

​ 说明:把每个依赖或调用的服务都隔离开来,防止级联失败引起整体服务不可用

​ Hystrix 隔离策略的区别如下:
img

1.2 熔断
说明:为了防止服务雪崩,类似家用电的保险丝,起到保护服务的作用

image-20211104144659799

1.3 降级
概念:接口出错时的兜底方法,以下图的4、5、6步能导致降级发生

image-20211104140236865

1.4 Hystrix 线程划分:

  1. 分组 commandGroup:代表某一个服务;如 order-server
  2. 命令名称 commandKey:代表服务的一个接口;如获取订单的接口
  3. 线程池划分:默认以分组划分,可以使线程池划分的提供粒度更小

总结:command group一般来说,可以是对应一个服务,多个command key对应这个服务的多个接口,多个接口的调用共享同一个线程池

1.5 注解:

@HystrixCommand

@HystrixProperty

例子:

@GetMapping("test")
@HystrixCommand(
    groupKey = "ConsumerControllerGroup",
    commandKey = "test",
    commandProperties = {
        @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_TIMEOUT_ENABLED, value = "false"),
        @HystrixProperty(name = HystrixPropertiesManager.REQUEST_CACHE_ENABLED, value = "false")
    }/*, fallbackMethod = "fallBack"*/,
    threadPoolProperties = {
        @HystrixProperty(name = HystrixPropertiesManager.CORE_SIZE, value = "200")
    })
public String test() throws InterruptedException {
    System.out.println("sleep");
    TimeUnit.SECONDS.sleep(4);
    System.out.println("4S 后的输出");
    return "test";
}

2. 配置属性

​ 4 种优先级别配置;全局内置默认值 < 动态全局配置属性 < 内置实例默认值 < 实例配置属性

  • 全局内置默认值:写死在代码里面的配置;HystrixCommandProperties、HystrixPropertiesManager
  • 全局动态配置属性:通过配置文件配置全局的值;hystrix.command.default.xxx.x
  • 内置类实例默认值:写死在代码里的实例的值;
  • 类实例配置属:通过配置文件配置特定实例的值;hystrix.command.${HystrixCommandKey}.xxx.x

2.1 Command 属性

​ 2.1.1 execution 配置

​ execution 配置控制的是 HystrixCommand.run() 的执行

配置 说明 默认值
execution.isolation.strategy 配置 HystrixCommand.run() 的执行隔离策略;可选:THREAD、SEMAPHORE THREAD
execution.isolation.thread.timeoutInMilliseconds 该属性用来配置 HystrixCommand 执行的超时时间,单位为毫秒 。当Hystri xCommand 执行时间超过该配置值之后,Hystrix 会将该执行命令标记为 TIMEOUT 并进入服务降级 处理逻辑 。 1000 毫秒(1秒)
execution.timeout.enable 用来配置 HystrixCommand.run() (默认为同步执行),的执行是否启用超时时间。 true
execution.isolation.semaphore.maxConcurrentRequests 仅隔离策略为 **SEMAPHORE **时生效,配置该属性的信号量的大小(并发请求数)。不够信号量,则请求会被拒绝。 10

​ 2.1.2 fallback 配置(信号量、线程池隔离策略都适用)

​ 以下这些属性用来控制HystrixCommand.getFallback() 的执行

配置 说明 默认值
fallback.isolation.semaphore.maxConcurrentRequests 方法的最大调用数;假设置为10,如果有11个请求 fallback 了,多出的 1 个请求则直接报错,不会再执行 fallback,因为没有 fallback 可用了。 10
fallback enable 是否启用降级策略 true

​ 2.1.3 circuitBreaker 配置

​ 用来控制 HystrixCircuitBreaker.java 熔断的行为

配置 说明 默认值
circuitBreaker.enable 是否启用断路器 true
circuitBreaker.requestVolumeThreadshold 滑动窗口时间内请求数不能超过该配置,如果超过是否熔断还需要再判断错误率。 20
circuitBreaker.sleepWindowInMilliseconds 断路器打开后的休眠时间,休眠时间结束后会尝试检测是否能够关闭断路器 5000
circuitBreaker.errorThresholdPercentage 断路器打开的错误的百分比条件 50%
circuitBreaker.foreceOpen 强制开启断路器 false
circuitBreaker.foreceClose 强制关闭断路器 false

image-20211105153004722

2.1.5 threadPool 属性

​ 指定隔离策略为线程池时的配置;全局配置前缀 hystrix.threadpool.default。以下配置类似 ThreadPoolExecutor

配置 说明 默认值
coreSize 核心线程数 10
maxQueueSize 线程池等待队列大小。设置-1使用 SynchronousQueue实现,否则使用LinkedBlockingQueue实现 -1
queueSizeRejectionThreshold 队列拒绝阈值,该参数即使队列没有达到最大值也能拒绝请求。对LinkedBlockingQueue队列的补充,因为LinkedBlockingQueue不能动态修改它的对象大小。 5
metrics.rollingStats.timeInMilliseconds 该参数用来设置滚动时间窗的长度 10000
metrics.rollingStats.numBuckets 设置滚动时间窗被划分成 “桶” 的数量 10

注意:metrics.rollingStats.timeInMilliseconds 参数必须能被 metrics.rollingStats.numBuckets 整除

线程池隔离策略共享请求信息
区分以下三个 ThreadLocal

  • ThreadLocal
  • InheritableThreadLocal
  • TransmittableThreadLocal

import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.concurrent.Callable;

/**
 * 此类能够保证:RequestContext 请求上下文,也就是 RequestAttributes 能够在线程池里自动有效
 *
 * @author Administrator
 */
@Component
@Log4j2
public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy implements ApplicationContextAware {

    @Value(value = "${hystrix.command.default.execution.isolation.strategy:THREAD}")
    private String strategy;

    @Override
    public <T> Callable<T> wrapCallable(Callable<T> callable) {
        return new RequestAttributeAwareCallable<>(callable, RequestContextHolder.getRequestAttributes());
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (!HystrixCommandProperties.ExecutionIsolationStrategy.THREAD.name().equals(strategy)) {
            return;
        }

        log.info("Hystrix ---- 启用共享 RequestContext 请求上下文信息");
        HystrixPlugins.getInstance().registerConcurrencyStrategy(new RequestContextHystrixConcurrencyStrategy());
    }

    private static class RequestAttributeAwareCallable<T> implements Callable<T> {
        private final Callable<T> delegate;
        private final RequestAttributes requestAttributes;

        public RequestAttributeAwareCallable(Callable<T> callable, RequestAttributes requestAttributes) {
            this.delegate = callable;
            this.requestAttributes = requestAttributes;
        }

        @Override
        public T call() throws Exception {
            // 执行之前绑定上下文,执行完成后释放
            try {
                RequestContextHolder.setRequestAttributes(requestAttributes);
                return delegate.call();
            } finally {
                RequestContextHolder.resetRequestAttributes();
            }
        }
    }
}

参考:

https://blog.csdn.net/zhuyu19911016520/article/details/85346065

https://blog.csdn.net/qq_42046105/article/details/84000988

https://zhuanlan.zhihu.com/p/59109781

Spring Cloud微服务实战


版权声明:本文为qq_39363204原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>