线程池/信号量
THREAD(线程隔离)
使用该方式,HystrixCommand将会在单独的线程上执行,并发请求受线程池中线程数量的限制。不同服务通过使用不同线程池,彼此间将不受影响,达到隔离效果。
hystrix将使用独立的线程池对应每一个服务提供者,用于隔离和限制这些服务。于是某个服务提供者的高延迟或者资源受限只会发生在该服务提供者对应的线程池中。
SEMAPHORE(信号量隔离)
其实就是个计数器,使用该方式,HystrixCommand将会在调用线程上执行,通过信号量限制单个服务提供者的并发量,开销相对较小(因为不用那么多线程池),并发请求受到信号量个数的限制。
Hystrix中默认并且推荐使用线程隔离(THREAD),
一般来说,只有当调用负载异常高时(例如每个实例每秒调用数百次)才需要信号量隔离,因为这种场景下使用THREAD开销会比较高。信号量隔离一般仅适用于非网络调用的隔离。
正常情况下,默认为线程隔离, 保持默认即可。
线程池和信号量都支持熔断和限流。相比线程池,信号量不需要线程切换,因此避免了不必要的开销。但是信号量不支持异步,也不支持超时,也就是说当所请求的服务不可用时,信号量会控制超过限制的请求立即返回,但是已经持有信号量的线程只能等待服务响应或从超时中返回,即可能出现长时间等待。线程池模式下,当超过指定时间未响应的服务,Hystrix会通过响应中断的方式通知线程立即结束并返回。
源码
配置源码
String groupKey() default "";
String commandKey() default "";
String threadPoolKey() default "";
String fallbackMethod() default "";
HystrixProperty[] commandProperties() default {};
HystrixProperty[] threadPoolProperties() default {};
Class<? extends Throwable>[] ignoreExceptions() default {};
ObservableExecutionMode observableExecutionMode() default ObservableExecutionMode.EAGER;
HystrixException[] raiseHystrixExceptions() default {};
String defaultFallback() default "";
包裹请求
HystrixCommandAspect切面
被注解@HystrixCommand修饰的方法,会被HystrixCommand包装执行,通过切面来实现。
1、先包裹请求
2、执行调用
3、异常返回
ExcuteType,根据返回值类型决定同步异步,Future为异步回调,其他均为同步
断路器
核心接口:com.netflix.hystrix.HystrixCircuitBreaker 实现类:HystrixCircuitBreakerImpl
一个Command key (也就是method)对应一个HystrixCircuitBreaker。
public boolean allowRequest();//是否允许命令执行
public boolean isOpen();//断路器是否打开(开关)
void markSuccess();//在半开状态时,执行成功反馈。将半开转为关闭。
void markNonSuccess();//在半开状态时,执行失败反馈。将半开转为打开。
统计命令
com.netflix.hystrix.HystrixMetrics
public static class HealthCounts {
private final long totalCount;执行总数
private final long errorCount;失败数
private final int errorPercentage;失败百分比
失败回滚
AbstractCommand的方法executeCommandAndObserve的局部变量:handleFallback(final Func1<Throwable, Observable<R>> handleFallback)
如果失败,走失败逻辑。