Hystrix处理流程简述

319 阅读3分钟

一、Hystrix的整体流程

image

1、构造HystrixCommand或HystrixObservableCommand对象

HystrixCommand command = new HystrixCommand(arg1, arg2);
HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);

2、执行Command

image

hystrix命令执行最终都是调用的toObservable方法,后面我们再解析

// 同步
K             value   = command.execute();
// 异步
Future<K>     fValue  = command.queue();
// 异步调用,获取Observable
Observable<K> ohValue = command.observe();         //hot observable
// 调用toObservable会立即执行hystrix命令
Observable<K> ocValue = command.toObservable();    //cold observable

3、是否命中缓存

当request cache开启并且命中缓存逻辑,那么就会直接返回结果

4、断路器是否打开状态

判断当前是否出发熔断 触发熔断就会获取fallback信息返回,否则往下处理

5、线程池/队列/信号量是否已经满了?

判断线程池、队列状态,如果满了就会走到fallback逻辑

6、执行command的构造函数或者运行command

7、计算断路器的健康状况

根据hystrix记录的成功、失败、拒绝、超时等信息,判断当前是否熔断 触发熔断就不会处理任何请求直到超过恢复间隔

8、获取fallback信息

用来做熔断、失败等异常处理的,这个很重要

9、返回正确的结果

二、断路器

断路器的逻辑:

  1. 当qps(HystrixCommandProperties.circuitBreakerRequestVolumeThreshold())或者错误占比(HystrixCommandProperties.circuitBreakerErrorThresholdPercentage())达到一定的阈值就会将断路器的开关状态从CLOSE置为OPEN
  2. 当超过休眠时间(HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds())之后,此时断路器状态为半开状态,如果下一个请求还是失败那么断路器就会变成开启状态,成功就会切换成CLOSE状态

image

1、断路器的计算规则?

  1. 断路器是通过滚动窗口(默认10s)来计算是否触发开关开启
  2. 每个窗口会有多个bucket(默认10个),bucket中存放当前桶所在时间段(比如1s一个桶)错误数量、成功数量、超时、拒绝的数据量,这样可以计算错误占比、总请求量
  3. 另外99th的计算也是通过滚动窗口(默认60s)+bucket来实现,记录每个请求的耗时,但是可以设置桶的数量和每个桶最多存放的样本数量

三、隔离

  1. hystrix采用舱壁模式将服务和它的依赖隔离开,并且限制每一个服务的并发
  2. hystrix隔离有线程池和信号量两个实现方式

image

1、线程池

  1. 线程池是hystrix使用的一种隔离方式
  2. 它是将服务的每个依赖作为一个线程池来进行隔离

2、信号量semaphore

1、在fallback场景执行 2、在执行时用来限制并发量的场景 3、由于semaphore的特性,当所有线程处于阻塞时那么就不能接受请求,除非超时

四、请求合并

  1. 所谓请求合并,就是将用户对于某个依赖的多个请求合并成一次请求,减少线程创建以及连接创建的开销,具体如下图
  2. 请求合并分为全局级别和requestcontext级别

image

1、请求合并的流程图

  1. 请求合并中bacth请求发送周期是10ms一次,每隔10ms就会从RequestQueue中拉去当前的队列数据进行合并发送
  2. 请求折叠是自动完成的,这里面包含一些batch reponse的处理

image

五、请求缓存

  1. 避免HystixCommand去做重复的工作
  2. 不同hystrixCommand的执行方式都是可以命中缓存的,比如execute和queue等