Envoy Adaptive-Concurrency Filter浅解

简介: 1. Why在通常情况下,我们希望服务在超出负载能力时能主动拒绝掉超额的请求,从而防止服务被击垮。达到这一目的传统手段是使用熔断能力,通过服务网格的DestinationRule可以配置基础的熔断能力,但这要求用户必须给出一个触发熔断的阈值,例如给出具体的pending requests数量,服务网格数据平面将在网络访问超出熔断配置时拒绝请求。这种做法对运维人员提出了要求:必须事先知道或估算出服务

1. Why

在通常情况下,我们希望服务在超出负载能力时能主动拒绝掉超额的请求,从而防止服务被击垮。达到这一目的传统手段是使用熔断能力,通过服务网格的DestinationRule可以配置基础的熔断能力,但这要求用户必须给出一个触发熔断的阈值,例如给出具体的pending requests数量,服务网格数据平面将在网络访问超出熔断配置时拒绝请求。这种做法对运维人员提出了要求:必须事先知道或估算出服务的负载能力,依此来做出熔断配置,但是在很多时候,想准确地估算服务的承受能力(特别是对于非开发者的运维人员来说)是较为困难的,这通常需要运维人员基于生产环境的运行状况进行多轮配置优化才能最终得到一个合理的设置,而一旦开发人员对组件进行了升级或变更,则之前测得的结果可能就立刻不作数了。为了解决这个问题,在一些语言框架中不乏有已经广为人知的方案,例如Netflix开源的concurrency-limits

2. What

作为时下云原生的明星项目--Envoy则通过Adaptive-Concurrency Filter提供了自适应并发限制能力, 其在运行期间会不断地对当前并发限制值之下的服务响应时间进行采样,同时定期将并发限制值缩小到一个较低值,再进行理想响应时间采样,然后再对二者进行对比得到当前并发限制设定下的实际响应时间与理想响应时间的差距,便可以通过该差值经一定算法判定出当前并发值是是否超过了服务的负载能力,超过了多少,进而动态地对并发限制进行调整,尽可能使得并发限制数量在服务可承受的范围附近,同时拒绝超出该限制的请求(返回HTTP 503及错误信息reached concurrency limit),实现保护服务的作用。

Envoy作为服务网格的Sidecar/网关时,则使得任意语言编写的应用在无需修改任何代码的情况下,就可以获得自适应并发限制的能力,极大地降低了运维工作的负担。

3. How

3.1 负载测定

接下来我们看看Adaptive-Concurrency Filter的算法,一窥其如何计算并发限制的核心机制。为了动态地计算并发值,我们在前文中提到,需要不停地测定实际延迟和理想延迟,并对二者做对比,为了表述方便,我们分别将其称为sampleRTT和minRTT,sampleRTT偏离minRTT越多,则说明服务超载越严重,我们可以用二者的比值来量化地反映这一程度,我们将其称为gradient(梯度或倾斜度),也即gradient越大,服务超载越严重,注意,sampleRTT比minRTT的比值只有大于1时表明服务超出负载,然而小于1时并不能理解为服务很空闲,这是因为minRTT已经是最小延迟了,如果测得的延迟比最小延迟还小,那只能说明是网络的正常波动导致,而不是服务负载变化导致。(除非测得的minRTT是不可信的,例如minRTT采样期间的并发值配置的太大,以至于超出了服务的负载)。为了容忍一定范围内的网络波动,我们在计算gradient时为sampleRTT加上一个小小的阈值,这个阈值应当是与合理地网络延迟波动范围相近的,这样一来,我们就可以尽量避免sampleRTT比minRTT<1的情况,我们称该值为B。这样一来我们就得到了如下公式:

基于gradient,我们便可以大致得到一个服务的超载情况了,如果gradient ≈ 1,则表明应用还尚未达到瓶颈,可以增加负载,直到计算出来的gradient大于1,我们再降低负载,如此往复,施加给应用的压力将始终被控制在瓶颈附近。

3.2 负载放大

如果测定的负载表明服务当前仍有余量,那么我们便需要对应用加压,也即放大并发限制,使其尽可能发挥性能。我们对这个增量值取名为headroom,headroom的计算Envoy使用了如下算法(limit(old)表示上一次计算得出的限制值):

最终再将L + headroom得出新的并发限制

4. Result

在启用AdaptiveConcurrency的集群中进行测试,对应用施加远超其负载的压力。查看Dashboard,可以看到,ConcurrencyLimit被限制在400 - 600之间浮动,这说明应用的负载能力在400-600之间,RqBlocked面板展示了被拒绝的请求数量,曲线持续增长,符合我们的预期。

5. Summary

通过以上内容,本文粗浅地解析了Envoy中Adaptive-Concurrency Filter的原理,疏漏不周之处还望各位不吝指教。自适应限流极大地降低了运维负担,增加了运维信心,在很多场景下都是相当值得选用的方案。但由于Envoy的最主要使用场景Istio尚不支持对AdaptiveConcurrency进行配置,而通过Istio EnvoyFilter API自行配置EnovyFIlter又相对较为复杂,阿里云服务网格ASM提供了ASMAdaptiveConcurrency API,可以使得用户仅关心相关业务参数,不必学习EnvoyFilter的配置规则即可方便地一步到位配置出自适应并发限制能力,该功能已经上线Beta版本,文档也将于近期上线官网,欢迎试用。

目录
相关文章
|
14天前
|
机器学习/深度学习 关系型数据库 Ruby
GitlabCI学习笔记之三:GitLabRunner pipeline语法之tags allow_faillure when retry timeout parallel
GitlabCI学习笔记之三:GitLabRunner pipeline语法之tags allow_faillure when retry timeout parallel
|
4月前
|
Oracle 关系型数据库
Adaptive Query Optimization
Adaptive Query Optimization
27 4
|
4月前
Adaptive Query Plans
Adaptive Query Plans
19 0
|
4月前
|
SQL
Adaptive Statistics
Adaptive Statistics
22 0
|
11月前
|
负载均衡 Dubbo 算法
Dubbo的Adaptive自适应机制原理与源码深度解析
Dubbo的Adaptive自适应机制原理与源码深度解析
145 0
|
监控 测试技术 Windows
JMeter 插件 Ultimate Thread Group 完成梯度递增场景的压测
前面几篇文章已经介绍完一个电商从注册登录到购物下单的典型场景的 Jmeter压测脚本,具体可参考前期文章:基于电商模式的性能测试(五)-基于Jmeter完成一次日常典型电商场景的压测(下单-支付)。 在实际压测前,我们还需要对场景做适当的调整。 从 ThreadGroup中看,我们的 Thread会在某个时间点同时起多个,而日常场景中我们需要的可能是一个递增的梯度加压的方式。 为了实现梯度
|
SQL 监控 算法
Adaptive Execution of Compiled Queries 论文解读
本篇是TUM的内存数据库HyPer针对compile-based执行框架的改进。其中涉及到HyPer的动态编译和并行执行框架 动态编译文章的结尾提到了编译执行系统存在的2个问题,其中之一就是:不可控的编译时间。
472 0
Adaptive Execution of Compiled Queries 论文解读
|
负载均衡 算法 安全
Envoy源码分析之Load balancing基础
# 什么是Load balancing? > Load balancing is a way of distributing traffic between multiple hosts within a single upstream cluster in order to effectively make use of available resources. There are man
1326 0
|
存储 网络协议 前端开发
Envoy源码分析之Stats基础
# 简介 Envoy官方文档中提到`One of the primary goals of Envoy is to make the network understandable`,让网络变的可理解,为了实现这个目标Envoy中内置了`stats`用于统计各类网络相关的指标,Envoy没有选择使用`Prometheus`SDK,而是选择自己实现了`stats`,[目的是为了适配Envoy的线
1587 0
Envoy源码分析之Stats基础