Hystrix

作者: 乌鲁木齐001号程序员 | 来源:发表于2020-07-08 12:58 被阅读0次

Hystrix

  • Hystrix 是用于处理延迟和容错的开源库;
  • Hystrix 主要用于避免级联故障,提高系统弹性;
  • Hystrix 解决了由于扇出导致的“雪崩效应”;
  • Hystrix 的核心是“隔离术”和“熔断机制”;
关键词
  • 扇出:服务的调用关系像一个思维导图;
  • 雪崩:下游的服务挂了,上游的所有服务都超时;某个节点挂了,所有的流量都会打在另一个节点上,导致另一个节点也挂了,进而导致更多的节点挂了;

Hystrix | 主要作用

  • 服务隔离和服务熔断;
  • 服务降级、快速失败和限流;
  • 请求合并和请求缓存;
  • 自带单体和集群监控;

Hystrix | 主要步骤

Hystrix 架构图.png
  1. 调用 Main 方法
    1.1 Command
    1.2 ObservableCommand
  2. .execute() / .queue() / .observe() / .toObservable()
  3. 判断有没有请求缓存和请求合并,一定要开启 HystrixRequestContext
  4. 熔断有没有开启
  5. 限流有没有触发(线程池 / 信号量)
  6. 执行业务方法
    6.1 业务执行有没有失败
    6.2. 业务执行有没有超时
  7. 熔断健康检查
  8. 所有的失败都会触发 fallback
  9. 业务直接返回

Hystrix | 两种命令模式

两种命令模式,可以分别执行:.execute().queue().observe().toObservable()

  • HystrixCommand
    • .execute()
    • .queue()
  • HystrixObservableCommand
    • .observe()
    • .toObservable()

.observe().toObservable() 的区别

  • .toObservable()new Subscriber<String>(){...} 中的 onNext() 可以集成正式的业务逻辑,在 run() 方法之外的业务逻辑;
  • .observe() 是 Hot 处理,在处理的过程中加载了一些东西,先执行 Commandrun() 方法,再加载 / 注册 Subscriber 对象;
  • .toObservable() 是 Cold 处理,在执行之前就全部加载完,然后一次执行完,先加载 / 注册 Subscriber 对象,再执行 Commandrun() 方法;
  • .toObservable() 每次订阅都需要一个新的对象;

HystrixCommand 和 HystrixObservableCommand 的区别

  • HystrixCommand 以隔离的形式完成 run() 的调用,线程隔离;
  • HystrixObservableCommand 使用当前线程进行调用,信号量隔离,HystrixObservableCommand 一次可以执行多个命令;

Hystrix | GroupKey

  • GroupKey 可以给 Hystrix 做分组和报警之用;
  • GroupKey 将作为线程池的默认名称;

Hystrix | CommandKey

  • Hystrix 可以不填写 CommandKey;
  • 默认 Hystrix 会通过反射类名命名 CommandKey;
  • 可以在 Setter 中加入 .andCommandKey() 来命名;

Hystrix | 请求缓存

  • Hystrix 支持将请求结果缓存在本地;
  • 通过实现 getCacheKey 方法来判断,是否取出缓存;
  • 请求缓存要求 Command 必须在同一个上下文中;
  • 通过 .withRequestCacheEnabled(true) 开启请求缓存;

Hystrix | 请求合并

  • Hystrix 支持将多个请求合并成一次请求;
  • Hystrix 请求合并要求两次请求必须足够“近”,默认的阈值是 500ms;
  • 请求合并分为局部合并和全局合并;
  • Collapser 可以设置相关参数;

Hystrix | 隔离术

ThreadPoolKey
  • 隔离一般都会用到线程池,线程池的话,一般都会起一个名字;
  • Hystrix 可以不填 ThreadPoolKey;
  • 默认 Hystrix 会用 GroupKey 命名线程池;
  • 在 Setter 中加入 andThreadPoolKey 进行命名;
隔离介绍
  • Hystrix 提供了信号量线程两种隔离手段;
  • 线程隔离会在单独的线程中执行业务逻辑;
  • 信号量的话就是基于信号量模型做的隔离,信号量的隔离在调用线程(Main Thread)上执行,但是调用的次数会做限制,超过这个次数的调用就不允许了;
隔离的好处
  • 比如一个请求进来了,请求了 3 个服务,3 个服务在 3 个隔离的线程中执行,2 个执行成功了,1 个失败了,失败的服务并不会影响其他线程的执行,可以快速失败;

Hystrix | 降级处理

降级
  • 降级是一种无奈的选择,就是俗称的备胎;
  • 比如打发票打不出来了,降级成友好的提示;
  • 比如商品页,推荐的商品显示不出来了,将提前缓存的商品信息显示在页面上;
  • Command 在降级的时候,需要实现 getFallback() 方法;
  • ObservableCommand 降级实现 resumeWithFallback() 方法;
降级触发原则
  • 除了 HystrixBadRequestException 之外的异常就会被降级;
  • 熔断开启的时候也会触发降级;
  • 线程池或信号量满的时候会被降级;
  • 业务异常会触发降级;
  • 业务超时会触发降级;
快速失败
  • Hystrix 提供了快速失败的机制,这个机制依赖的就是 getFallback(),当出现任何异常的时候,都会触发 getFallback(),getFallback() 就会把失败的业务快速返回给前端;
  • 当不实现 getFallback() 的时候,会将异常直接抛出,这也是一种快速失败;
快速失败的好处
  • 在系统相互依赖调用的时候,快速失败的存在,可以防止下游服务的不正常,卡住上游服务,进一步导致级联雪崩的情况;
  • 如果有快速失败,下游不正常的服务快速失败,上游服务就不会阻塞,业务还是可以正常办理 ;

Hystrix | 熔断机制

熔断器介绍
  • 熔断器是一种开关,用来控制流量是否执行业务逻辑;
  • 在熔断器打开的时候,永远执行 getFallback(),永远不执行业务逻辑;
熔断器核心指标

熔断器的开关,要么根据 3 个指标决定开关,要么强制决定开关。逻辑是这样的:在一个快照时间窗内,请求总数达到一定数后,看错误率,如果错误率超过阈值,打开熔断开关。

  • 快照时间窗:就是一个时间段;
  • 请求总数阈值:在快照时间窗内的请求总数;
  • 错误百分比阈值:在快照时间窗内,错误的内容达到一定比例,才触发熔断开关;
熔断器的核心
熔断器核心.png
  • 每一个格代表一段时间,比如 1s;
  • 没 10 个格会做一个汇总,就最后的白格;
  • 汇总的时候,如果发现:请求的总数到阈值了,并且错误率到阈值了就打开熔断器的开关;
  • 这写格是滚动的,新的一格接着队尾,就把队首的格丢掉;
  • 然后重新计算,如果不满足打开熔断器的条件,就将熔断器关闭;
熔断器的状态
  • 开启:所有请求对会进入 fallback 方法;
  • 半开启:在熔断器打开的状态下,熔断器会将请求每个几秒放过去一个,看看服务恢复了没有,如果恢复了,就关闭熔断器,如此往复循环;默认情况下,熔断器开启 5s 之后就会进入半开启状态;
  • 关闭:正常处理业务请求;
Hystrix | 两种应用场景
  • 隐式创建 HystrixCommand:影厅服务调影片服务的逻辑,被封装在 Command 的 run() 方法内,在 run() 方法内发送了一次 HTTP 调用;当整合了 Feign 和 Zuul 的时候,HTTP 的调用就已经整合进 HystrixCommand 中了;
  • 显示创建 HystrixCommand:Controller 调 Service 的逻辑被封装在 Command 的 run() 方法内;
Hystrix Dashboard | 图例
Hystrix Dashboard 图例.png
Hystrix Dashboard | 缺陷
  • 只能监控 2 分钟内的变化,不能监控长时间的变化,并且不够细致;
Hystrix | 设置线程池大小
  • Threadpool Size:比如系统的 QPS 是 3000,有 100 个节点,每个节点需要承载 30 的 QPS,请求的平均处理时间是 0.2s,那么需要的线程数就是 30 * 0.2 = 6 个线程,完了要加上 0.3~0.8 的冗余,比如线程切换之类的,差不多就是 10,Hystrix 默认的线程数量是 10,就可以承担 30 的 QPS;
  • Threadpool Size:Threadpool Size 的 1.5~2 倍就可以;

Hystrix | 常见参数

请求上下文
配置 配置描述
requestCache.enabled 是否开启请求缓存,默认为true
requestLog.enabled 是否开启请求日志,默认为true
maxRequestsInBatch 设置批处理中允许的最大请求数
timerDelayInMilliseconds 设置批处理创建到执行之间的毫秒数
线程池相关配置
配置 配置描述
coreSize 配置线程池大小,默认为10
keepAliveTimeMinutes 配置核心线程数空闲时keepAlived时长,默认1分钟
maxQueueSize 配置线程池任务队列大小,默认为-1
maximumSize 线程池中线程的最大数量,默认值是 10
queueSizeRejectionThreshold 任务队列的请求上线,默认值是10
allowMaximumSizeToDivergeFromCoreSize 是否开启最大线程数
execution.isolation.thread.timeoutInMilliseconds 设置超时时间
execution.isolation.thread.interruptOnTimeout 请求超时是否中断任务
execution.isolation.thread.interruptOnCancel 请求取消是否终端任务
熔断机制相关配置
配置 配置描述
circuitBreaker.enabled 是否开启熔断器
circuitBreaker.requestVolumeThreshold 启用熔断器功能窗口时间内的最小请求数
circuitBreaker.sleepWindowInMilliseconds 半熔断开启时间
circuitBreaker.errorThresholdPercentage 开启熔断的失败率阈值

相关文章

网友评论

      本文标题:Hystrix

      本文链接:https://www.haomeiwen.com/subject/bghwqktx.html