Hystrix工作原理(三)

Request Collapsing

您可以使用请求collapser(HystrixCollapser是抽象父级)来使用HystrixCommand,您可以使用它将多个请求折叠为单个后端依赖项调用。

下图显示了两种情况下的线程数和网络连接数:首先没有,然后是请求折叠(假设所有连接在短时间内都是“并发”,在本例中为10ms)。

Sequence Diagram 

@ adrianb11友好地提供了Request Collapsing的序列图。

Why Use Request Collapsing?

使用请求折叠来减少执行并发HystrixCommand执行所需的线程数和网络连接数。请求折叠以自动方式执行此操作,不会强制代码库的所有开发人员协调手动批处理请求。

Global Context (Across All Tomcat Threads)

理想的折叠类型是在全局应用程序级别完成的,因此任何Tomcat线程上的任何用户的请求都可以折叠在一起。

例如,如果您将HystrixCommand配置为支持对检索影片评级的依赖项的请求的任何用户进行批处理,那么当同一JVM中的任何用户线程发出此类请求时,Hystrix会将其请求与其他任何用户一起添加到同一JVM中崩溃的网络电话。

请注意,collapser会将单个HystrixRequestContext对象传递给折叠的网络调用,因此下游系统必须处理此情况才能使其成为有效选项。

User Request Context (Single Tomcat Thread)

如果将HystrixCommand配置为仅处理单个用户的批处理请求,则Hystrix可以从单个Tomcat线程(请求)中折叠请求。

例如,如果用户想要为300个视频对象加载书签,而不是执行300个网络调用,则Hystrix可以将它们全部合并为一个。

Object Modeling and Code Complexity

有时,当您创建对对象的使用者具有逻辑意义的对象模型时,这与对象的生产者的有效资源利用率不匹配。

例如,给定一个包含300个视频对象的列表,迭代它们并在每个视频对象上调用getSomeAttribute()是一个明显的对象模型,但如果天真地实现可以导致300个网络调用全部在相互之间的毫秒内完成(并且很可能是饱和的)资源)。

您可以通过手动方式处理此问题,例如在允许用户调用getSomeAttribute()之前,要求他们声明他们想要获取属性的视频对象,以便它们都可以预先获取。

或者,您可以划分对象模型,以便用户必须从一个位置获取视频列表,然后从其他位置请求该视频列表的属性。这些方法可能导致与心理模型和使用模式不匹配的笨拙的API和对象模型。

当多个开发人员在代码库上工作时,它们也可能导致简单的错误和低效率,因为对一个用例的优化可以通过实现另一个用例和通过代码的新路径来打破。

通过将折叠逻辑推送到Hystrix层,无论您如何创建对象模型,调用的顺序,或者不同的开发人员是否了解正在进行的优化或甚至需要完成优化。getSomeAttribute()方法可以放在最适合的地方,并以适合使用模式的方式调用,collapser会自动批量调用时间窗口。

What Is the Cost of Request Collapsing?

启用请求折叠的成本是在执行实际命令之前增加的延迟。最大成本是批处理窗口的大小。

如果你有一个执行中位数需要5毫秒的命令,以及10毫秒批处理窗口,那么在最坏的情况下执行时间可能会变为15毫秒。

通常情况下,请求不会像打开时那样提交给窗口,因此中值惩罚是窗口时间的一半,在这种情况下是5ms。确定此成本是否值得,取决于正在执行的命令。高延迟命令不会受到少量额外平均延迟的影响。此外,给定命令的并发数量是关键:如果很少有超过1或2个请求一起批处理,则无需支付罚金。

实际上,在单线程顺序迭代中,折叠将成为主要的性能瓶颈,因为每次迭代将等待10ms批处理窗口时间。但是,如果特定命令同时大量使用并且可以将数十个甚至数百个调用一起批量处理,那么由于Hystrix减少了所需的线程数量以及网络连接数量,因此实现的吞吐量通常远远超过了成本。依赖。

Collapser Flow

Request Caching

HystrixCommand和HystrixObservableCommand实现可以定义一个缓存密钥,然后用于以并发感知的方式对请求上下文中的调用进行重复数据删除。

这是一个涉及HTTP请求生命周期的示例流程,以及在该请求中工作的两个线程:

请求缓存的好处是:

不同的代码路径可以执行Hystrix命令,而无需担心重复的工作。

这在许多开发人员正在实现不同功能的大型代码库中特别有用。例如,通过所有需要获取用户的Account对象的代码的多个路径都可以像这样请求它:

Account account = new UserGetAccount(accountId).execute();
//or
Observable<Account> accountObservable = new UserGetAccount(accountId).observe();

Hystrix RequestCache将只执行一次底层run()方法,并且执行HystrixCommand的两个线程将接收相同的数据,尽管已实例化不同的实例。

  • 数据检索在整个请求中是一致的。

每次执行命令时,不是可能返回不同的值(或回退),而是为同一请求中的所有后续调用缓存并返回第一个响应。

  • 消除重复的线程执行。

由于请求缓存位于construct()或run()方法调用的前面,因此Hystrix可以在调用导致线程执行之前对其进行重复数据删除

如果Hystrix没有实现请求缓存功能,那么每个命令都需要在构造或运行方法中自己实现它,这将在线程排队并执行之后将其放入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值