简介
发现很多使用Hystrix的同学对Hystrix的理解都有一些问题,所以这里尝试用比较通俗易懂的方式来介绍一下Hystrix。
首先使用Hystrix的常用目的:降级(限流),熔断
绝大多数时候我们的资源是有限的,一般情况下使用是没有问题的,但是也会有流量高的时候。
举一个常见的例子:早上我们去上班,如果早一点,路上的人车都比较少,你可以随便走,都没有问题。但是当上班高峰期的时候,就会走走停停。当应用流量大的时候,情况也就是想这样的情况。
解决办法
-
依赖隔离:多少对依赖进行分组,使用不同的线程池。这就像我们的车道划分,我们知道一个车道如果出了车祸,就很容易拥堵。是因为资源没有划分,大家都使用一个车道,如果一个车道出车祸,这个车道的车就会使用其他的车道,让流量更高,很容易出再问题。如果每一辆车只能在固定的车道行驶,就会好很多。
-
降级:就是对于一个指定的服务如果执行超时,或者在一段时间内请求超过多少直接是否fallback快速返回。类似于交警设卡每分钟值允许多少车辆通过。
-
熔断:对于一个服务如果调用失败率达到一个指定的阈值,就直接拒绝服务。相当于交通管制,不让过。
怎样实现
这里有一些点很重要,有助于我们理解后面的一些配置。我们知道要实现降级和熔断需要一些统计信息。比如一个服务的执行时间,一个服务的失败率等。
Hystrix怎样知道这些信息呢?肯定得和服务发生联系。Hystrix采用的方式是使用命令模式来封装服务。
HystrixCommand和HystrixObservableCommand就相当于命令角色(Command)。
ConcreteCommand(具体命令角色)需要我们实现。
具体的服务就是扮演的Receiver角色
客服端就相当于Invoker角色
这样就相当于在具体的服务外面包装了一层,Hystrix就可以在Command中为服务分配线程,统计执行时间,统计服务失败率等。
关于统计这里还有2个重要的概念:时间窗口(metricsRollingStatisticalWindow)和段(bucket)
统计肯定是有时间周期才有意义,这个时间周期就叫做时间窗口。统计的服务失败率就是时间窗口类的失败率。默认的时间窗口是10000ms就是10秒。
举个例子,假设我们配置允许熔断,熔断的条件是服务调用失败率为80%,就表示10秒内: 调用这个服务失败的次数/调用这个服务的总次数>=80% 就拒绝服务。
至于Bucket则涉及到更加底层的一些东西。时间窗口内不是指执行一次数据收集,而是把时间窗口t划分为n段,每段收集一次信息放在Bucket中。这个稍后介绍时间窗口的时候再详细介绍。
Hystrix很容易上手,要应用很容易,随便搜索一下都有很多,接下来我们重点来看一下配置,看一下这些配置是怎样影响应用的。
配置的默认值是在HystrixCommandProperties、HystrixCollapserProperties、HystrixThreadPoolProperties类中。
熔断配置参数
circuitBreakerEnabled
是否允许熔断,默认true
circuitBreakerRequestVolumeThreshold
判断熔断的最少请求数,默认是20,只有在一个统计窗口内处理的请求数量达到这个阈值,才会进行是否熔断的判断
circuitBreakerErrorThresholdPercentage
判断熔断的阈值,默认值50,表示在一个统计窗口内有50%的请求处理失败,会触发熔断 注意:circuitBreakerEnabled为true,circuitBreakerErrorThresholdPercentage满足条件才会触发
circuitBreakerForceOpen
是否强制开启熔断器阻断所有请求,默认false,如果为true就会拒绝所有请求(服务调用)
circuitBreakerForceClosed
强制熔断器进入closed状态,默认false,如果是true,忽略错误百分比(circuitBreakerErrorThresholdPercentage)
优先级比circuitBreakerForceOpen低,也就是说circuitBreakerForceOpen设置为true,circuitBreakerForceClosed这个设置就是无效的。
circuitBreakerSleepWindowInMilliseconds
熔断时间,默认:5秒 当满足熔断条件,熔断器中断请求5秒后会进入半打开状态,放部分流量过去重试
执行配置参数
executionIsolationSemaphoreMaxConcurrentRequests
当隔离策略是ExecutionIsolationStrategy.SEMAPHORE,允许进入HystrixCommand.run()方法的最大并发请求数量。
executionIsolationStrategy
隔离策略,THREAD和SEMAPHORE 默认值: HystrixCommand: THREAD HystrixObservableCommand: SEMAPHORE
executionIsolationThreadInterruptOnTimeout
隔离执行,超时的时候是否中断,默认true
executionTimeoutInMilliseconds
指定超时时间,单位毫秒。执行超过指定时间就执行fallback函数
executionTimeoutEnabled
执行的时候是否允许超时
executionIsolationThreadPoolKeyOverride
使用哪一个线程池来执行(通过线程池名称来标识哪一个线程池来执行,没有就创建)
fallbackIsolationSemaphoreMaxConcurrentRequests
HystrixCommand.getFallback()执行的最大并发数,如果超过直接抛出异常,而不是执行fallback,默认值10
fallbackEnabled
是否允许fallback
统计配置
metricsRollingStatisticalWindowInMilliseconds
熔断统计时间窗口默认10秒,也就是说保留10秒的统计信息
metricsRollingStatisticalWindowBuckets
一个熔断统计窗口中的Bucket数量,默认10个
Bucket
Bucket不是一个配置,这里介绍Bucket帮助我们理解上面2个配置,我们先看一下Hystrix文档的一张图,有助于我们理解。
从上图看,是一个事件窗口,总共有10个Bucket,每一个Bucket中是一些统计的是1秒内的成功、失败、超时、拒绝的信息。
这些信息可以计算成功、失败、超时的百分比,然后执行相应的策略。
下面2组有点像,但是差别很大: metricsRollingStatisticalWindowInMilliseconds和metricsRollingStatisticalWindowBuckets是和熔断及线程池相关的
metricsRollingPercentileWindowInMilliseconds和metricsRollingPercentileWindowBuckets是和执行时间相关的
metricsRollingPercentileEnabled
是否开启执行延迟统计,默认true,服务的执行延迟会被追踪计算,如果是false所用统计均值百分比都会返回-1
metricsRollingPercentileWindowInMilliseconds
执行时间统计窗口,默认60s
metricsRollingPercentileWindowBuckets
执行时间统计窗口Bucket数量,默认6个
metricsRollingPercentileBucketSize
执行时间Bucket的最大值,最多保留的数量
metricsHealthSnapshotIntervalInMilliseconds
计算成功失败百分比的时间间隔,默认500ms
requestCacheEnabled
是否开启请求缓存,默认true
requestLogEnabled
是否开启请求日志,默认true
Collapser配置
maxRequestsInBatch
批量执行命令的最大值,默认Integer.MAX_VALUE
timerDelayInMilliseconds
批量执行命令之间的时间延迟,默认10ms
requestCacheEnabled
批量处理是否开启执行缓存,默认true
线程池配置
coreSize
默认10
maximumSize
最大值,默认10
maxQueueSize
默认-1,使用 SynchronousQueue,如果是设置为一个正数则使用LinkedBlockingQueue
queueSizeRejectionThreshold
最大排队数量,默认5,如果maxQueueSize == -1这该参数无效
allowMaximumSizeToDivergeFromCoreSize
是否允许coreSize和maximumSize不一致,默认false
keepAliveTimeMinutes
1.5.9之前无效,因为coreSize 等于 maximumSize,1.5.9及之后,当allowMaximumSizeToDivergeFromCoreSize设置为true的时候,并且coreSize < maximumSize,这个参数就是设置线程失效的时间。
Hystrix工作流程图
最后来看一张Hystrix工作流程图帮助我们理解: