什么是Hystrix?
在分布式环境中,许多服务依赖项中的一些不可避免地会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助我们控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、阻止跨服务的级联故障以及提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性。
hytrixd的历史
Hystrix是从Netflix API团队于2011年开始的弹性工程工作发展而来的。2012年,Hystrix继续发展和成熟,Netflix的许多团队都采用了它。如今,Netflix每天都通过Hystrix执行数百亿个线程隔离调用和数千亿个信号量隔离调用。这导致了正常运行时间和恢复能力的显著改善。
Hystrix是做什么的?
Hystrix设计用于执行以下操作:
-
从通过第三方客户端库访问的依赖项(通常通过网络)中保护和控制延迟和故障。
-
停止复杂分布式系统中的级联故障。
-
快速故障和快速恢复。
-
在可能的情况下,撤退并优雅地降级。
-
实现近实时监控、警报和操作控制。
Hystrix解决了什么问题?
复杂分布式体系结构中的应用程序有几十个依赖项,每个依赖项在某个时候都不可避免地会失败。如果主机应用程序没有与这些外部故障隔离开来,那么它就有被这些外部故障破坏的风险。
例如,对于依赖于30个服务的应用程序,其中每个服务的正常运行时间为99.99%,以下是我们可以期望的:
每月2小时以上的停机时间,即使所有依赖项都有出色的正常运行时间。
99.9930=99.7%的正常运行时间
10亿个请求的0.3%=300万次失败
现实情况通常更糟。
即使在所有依赖项都表现良好的情况下,如果我们不设计整个系统以实现恢复能力,那么几十个服务中的每一个服务即使有0.01%的停机时间,其总体影响也相当于一个月可能有几个小时的停机时间。
当一切正常时,请求流可以如下所示:
当许多后端系统中的一个变得潜在时,它可能会阻止整个用户请求:
在高流量的情况下,单个后端依赖性变得潜在可能会导致所有服务器上的所有资源在几秒钟内饱和。
应用程序中通过网络或进入客户端库的每个点都可能导致网络请求,这是潜在故障的根源。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,从而备份队列、线程和其他系统资源导致整个系统中造成更多级联故障。
当通过第三方客户机执行网络访问时,这些问题会加剧。第三方客户机是一个“黑匣子”,其中隐藏了实施细节,可以随时更改,并且每个客户机库的网络或资源配置都不同,通常难以监控和更改。
更糟糕的是,可传递依赖项在应用程序未显式调用的情况下执行可能代价高昂或容易出错的网络调用。
网络连接失败或降级。服务和服务器出现故障或变慢。新库或服务部署会更改行为或性能特征。客户端库有bug。
所有这些都表示需要隔离和管理的故障和延迟,以便单个故障依赖项不能关闭整个应用程序或系统。
Hystrix的工作:
-
防止任何单个依赖项耗尽所有容器(如Tomcat)用户线程。
-
卸载和快速故障,而不是排队。
-
在可行的情况下提供回退,以保护用户免受故障。
-
使用隔离技术(如隔板、泳道和断路器模式)限制任何一种依赖性的影响。
-
通过近实时度量、监视和警报优化发现时间
-
通过配置更改的低延迟传播和对Hystrix大多数方面动态属性更改的支持来优化恢复时间,从而允许我们使用低延迟反馈循环进行实时操作修改。
-
保护整个依赖关系客户端执行过程中的故障,而不仅仅是网络流量。
Hystrix如何实现其目标?
- 将对外部系统(或“依赖项”)的所有调用包装到通常在单独线程中执行的HystrixCommand或HystrixObservableCommand对象中(这是命令模式的一个示例)。
- 超时花费时间超过我们定义的阈值的呼叫。有一个默认值,但是对于大多数依赖项,我们可以通过“properties”自定义设置这些超时,以便它们略高于每个依赖项的测量99.5%的性能。
- 为每个依赖项维护一个小线程池(或信号量);如果已满,则发送给该依赖项的请求将立即被拒绝,而不是排队。
-
测量成功、失败(客户端引发的异常)、超时和线程拒绝。
-
如果服务的错误百分比超过阈值,则手动或自动跳闸断路器,在一段时间内停止对特定服务的所有请求。
-
当请求失败、被拒绝、超时或短路时执行回退逻辑。
-
近实时监控指标和配置更改。
当我们使用Hystrix包装每个基础依赖项时,上图中所示的体系结构将更改为类似下图。每个依赖项彼此隔离,在发生延迟时,它可能会饱和的资源受到限制,并包含在回退逻辑中,该逻辑决定在依赖项中发生任何类型的故障时做出何种响应: