Netflix Hystrix笔记

语境

  • 微服务架构下,各服务之间的依赖层级关系复杂,甚至成网状
  • 依赖:A调用B,称为A依赖B,也可称A有一个对B对依赖
  • Client:依赖的形式基本上是A使用B提供的client来调用B,也可以是A使用HttpClient这样的通用client来调用B

能做什么?

  • 避免因一个节点的超时,导致下游节点级联式的请求堆积,崩溃整个系统
  • 避免对一个故障节点发出请求,节省网络资源
  • 快速失败
  • 相对快速的恢复:侦测节点,恢复通信
  • 熔断时的降级
  • 一些报警,监控,运行时控制的功能
  • hystrix不仅仅局限于网络通信,用在其他地方也是可以的

设计原则

  • 防止单个依赖用尽容器(如Tomcat)的所有线程
  • 使用减载和快速失败,而不是排队
  • 提供fallback
  • 使用隔离技术(隔离舱,泳道,熔断器模式)限制单个依赖所能产生的影响
  • 防止整个客户端的执行失败,而不只是网络流量
  • 支持运行时修改配置

架构

  • 对外部系统调用的包装:HystrixCommand、HystrixObservableCommand
  • 超时阈值:建议稍微低于99.5%线
  • 每个依赖有一个小线程池或者信号量:线程池满了的话则直接拒绝
  • 指标:成功数、失败数(客户端异常数)、超时数、线程拒绝数
  • 熔断:错误数超过比例自动熔断,也可手动熔断
  • fallback(降级):请求失败时、超时时、拒绝时、熔断时
  • 近实时修改:监控指标和配置变更

断路器

三个状态:OPEN、CLOSED、HALF-OPEN

OPEN

意思:断开,请求被直接短路 触发条件:

  1. 当断路器流量达到基础值
  2. failure比例到达设定阈值

维持时间:通过参数控制,比如1秒

CLOSED

意思:闭合,请求可以通过

HALF-OPEN

意思:半开,如果下一个请求成功则闭合,否则断开 触发条件:在OPEN之后过了一段时间变成半开状态,时间可设置 状态迁移:

  • 在HALF-OPEN之后第一个请求成功 -> CLOSED
  • 失败 -> OPEN

隔离机制

线程池

  • 为单个Client提供一个线程池(5-20个线程)
  • 将Caller线程(如Tomcat线程)和实际工作线程解耦
  • 不会阻塞Caller线程
  • 开销:任务排队、调度、上下文切换

信号量

  • 为单个Client提供一个Semaphore
  • caller线程和实际工作线程同一个
  • 会阻塞Caller线程
  • 开销:比线程池模式小多了

请求折叠

  • 在一段时间里对同一个依赖的请求折叠起来,变成一个请求,降低对依赖的实际并发数,比如把get 100个id的动作合并成一个
  • 怎么折叠要用户自己实现
  • 代价:会增加一定的延迟,因为要等待一批请求折叠起来

请求缓存

  • 把在同一请求上下文内的重复请求去重,比如在同一请求内,调用了两次getById(1)
  • 在代码复杂的时候,你很难避免重复调用的代码路径存在

版权

评论