wordpress页面列表小工具,潮州短视频seo推广,seo域名综合查询,react是网站开发转载自 流量控制
概述
流量控制#xff08;flow control#xff09;#xff0c;其原理是监控应用流量的 QPS 或并发线程数等指标#xff0c;当达到指定的阈值时对流量进行控制#xff0c;以避免被瞬时的流量高峰冲垮#xff0c;从而保障应用的高可用性。
FlowSlot 会…转载自 流量控制
概述
流量控制flow control其原理是监控应用流量的 QPS 或并发线程数等指标当达到指定的阈值时对流量进行控制以避免被瞬时的流量高峰冲垮从而保障应用的高可用性。
FlowSlot 会根据预设的规则结合前面 NodeSelectorSlot、ClusterBuilderSlot、StatisticSlot 统计出来的实时信息进行流量控制。
限流的直接表现是在执行 Entry nodeA SphU.entry(resourceName) 的时候抛出 FlowException 异常。FlowException 是 BlockException 的子类您可以捕捉 BlockException 来自定义被限流之后的处理逻辑。
同一个资源可以创建多条限流规则。FlowSlot 会对该资源的所有限流规则依次遍历直到有规则触发限流或者所有规则遍历完毕。
一条限流规则主要由下面几个因素组成我们可以组合这些元素来实现不同的限流效果
resource资源名即限流规则的作用对象count: 限流阈值grade: 限流阈值类型QPS 或并发线程数limitApp: 流控针对的调用来源若为 default 则不区分调用来源strategy: 调用关系限流策略controlBehavior: 流量控制效果直接拒绝、Warm Up、匀速排队
基于QPS/并发数的流量控制
流量控制主要有两种统计类型一种是统计并发线程数另外一种则是统计 QPS。类型由 FlowRule 的 grade 字段来定义。其中0 代表根据并发数量来限流1 代表根据 QPS 来进行流量控制。其中线程数、QPS 值都是由 StatisticSlot 实时统计获取的。
我们可以通过下面的命令查看实时统计信息
curl http://localhost:8719/cnode?idresourceName
输出内容格式如下
idx id thread pass blocked success total Rt 1m-pass 1m-block 1m-all exception
2 abc647 0 46 0 46 46 1 2763 0 2763 0其中
thread 代表当前处理该资源的并发数pass 代表一秒内到来到的请求blocked 代表一秒内被流量控制的请求数量success 代表一秒内成功处理完的请求total 代表到一秒内到来的请求以及被阻止的请求总和RT 代表一秒内该资源的平均响应时间1m-pass 则是一分钟内到来的请求1m-block 则是一分钟内被阻止的请求1m-all 则是一分钟内到来的请求和被阻止的请求的总和exception 则是一秒内业务本身异常的总和。
2.1 并发线程数控制
并发数控制用于保护业务线程池不被慢调用耗尽。例如当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加对于调用者来说意味着吞吐量下降和更多的线程数占用极端情况下甚至导致线程池耗尽。为应对太多线程占用的情况业内有使用隔离的方案比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢线程池隔离。这种隔离方案虽然隔离性比较好但是代价就是线程数目太多线程上下文切换的 overhead 比较大特别是对低延时的调用有比较大的影响。Sentinel 并发控制不负责创建和管理线程池而是简单统计当前请求上下文的线程数目正在执行的调用数目如果超出阈值新的请求会被立即拒绝效果类似于信号量隔离。并发数控制通常在调用端进行配置。
例子参见ThreadDemo
2.2 QPS流量控制
当 QPS 超过某个阈值的时候则采取措施进行流量控制。流量控制的效果包括以下几种直接拒绝、Warm Up、匀速排队。对应 FlowRule 中的 controlBehavior 字段。 注意若使用除了直接拒绝之外的流量控制效果则调用关系限流策略strategy会被忽略。 直接拒绝
直接拒绝RuleConstant.CONTROL_BEHAVIOR_DEFAULT方式是默认的流量控制方式当QPS超过任意规则的阈值后新的请求就会被立即拒绝拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下比如通过压测确定了系统的准确水位时。具体的例子参见 FlowQpsDemo。
Warm Up
Warm UpRuleConstant.CONTROL_BEHAVIOR_WARM_UP方式即预热/冷启动方式。当系统长期处于低水位的情况下当流量突然增加时直接把系统拉升到高水位可能瞬间把系统压垮。通过冷启动让通过的流量缓慢增加在一定时间内逐渐增加到阈值上限给冷系统一个预热的时间避免冷系统被压垮。详细文档可以参考 流量控制 - Warm Up 文档具体的例子可以参见 WarmUpFlowDemo。
通常冷启动的过程系统允许通过的 QPS 曲线如下图所示 匀速排队
匀速排队RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER方式会严格控制请求通过的间隔时间也即是让请求以均匀的速度通过对应的是漏桶算法。详细文档可以参考 流量控制 - 匀速器模式具体的例子可以参见 PaceFlowDemo。
该方式的作用如下图所示 这种方式主要用于处理间隔性突发的流量例如消息队列。想象一下这样的场景在某一秒有大量的请求到来而接下来的几秒则处于空闲状态我们希望系统能够在接下来的空闲期间逐渐处理这些请求而不是在第一秒直接拒绝多余的请求。 注意匀速排队模式暂时不支持 QPS 1000 的场景。 基于调用关系的流量控制
调用关系包括调用方、被调用方一个方法又可能会调用其它方法形成一个调用链路的层次关系。Sentinel 通过 NodeSelectorSlot 建立不同资源间的调用的关系并且通过 ClusterBuilderSlot 记录每个资源的实时统计信息。
有了调用链路的统计信息我们可以衍生出多种流量控制手段。
3.1 根据调用方限流
ContextUtil.enter(resourceName, origin) 方法中的 origin 参数标明了调用方身份。这些信息会在 ClusterBuilderSlot 中被统计。可通过以下命令来展示不同的调用方对同一个资源的调用数据
curl http://localhost:8719/origin?idnodeA
调用数据示例
id: nodeA
idx origin threadNum passedQps blockedQps totalQps aRt 1m-passed 1m-blocked 1m-total
1 caller1 0 0 0 0 0 0 0 0
2 caller2 0 0 0 0 0 0 0 0上面这个命令展示了资源名为 nodeA 的资源被两个不同的调用方调用的统计。
流控规则中的 limitApp 字段用于根据调用来源进行流量控制。该字段的值有以下三种选项分别对应不同的场景
default表示不区分调用者来自任何调用者的请求都将进行限流统计。如果这个资源名的调用总和超过了这条规则定义的阈值则触发限流。{some_origin_name}表示针对特定的调用者只有来自这个调用者的请求才会进行流量控制。例如 NodeA 配置了一条针对调用者caller1的规则那么当且仅当来自 caller1 对 NodeA 的请求才会触发流量控制。other表示针对除 {some_origin_name} 以外的其余调用方的流量进行流量控制。例如资源NodeA配置了一条针对调用者 caller1 的限流规则同时又配置了一条调用者为 other 的规则那么任意来自非 caller1 对 NodeA 的调用都不能超过 other 这条规则定义的阈值。
同一个资源名可以配置多条规则规则的生效顺序为{some_origin_name} other default
3.2 根据调用链路入口限流链路限流
NodeSelectorSlot 中记录了资源之间的调用链路这些资源通过调用关系相互之间构成一棵调用树。这棵树的根节点是一个名字为 machine-root 的虚拟节点调用链的入口都是这个虚节点的子节点。
一棵典型的调用树如下图所示 machine-root/ \/ \Entrance1 Entrance2/ \/ \DefaultNode(nodeA) DefaultNode(nodeA)上图中来自入口 Entrance1 和 Entrance2 的请求都调用到了资源 NodeASentinel 允许只根据某个入口的统计信息对资源限流。比如我们可以设置 strategy 为 RuleConstant.STRATEGY_CHAIN同时设置 refResource 为 Entrance1 来表示只有从入口 Entrance1 的调用才会记录到 NodeA 的限流统计当中而不关心经 Entrance2 到来的调用。
调用链的入口上下文是通过 API 方法 ContextUtil.enter(contextName) 定义的其中 contextName 即对应调用链路入口名称。详情可以参考 ContextUtil 文档。
3.3 具有关系的资源流量控制关联流量控制
当两个资源之间具有资源争抢或者依赖关系的时候这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢读的速度过高会影响写得速度写的速度过高会影响读的速度。如果放任读写操作争抢资源则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢举例来说read_db 和 write_db 这两个资源分别代表数据库读写我们可以给 read_db 设置限流规则来达到写优先的目的设置 strategy 为 RuleConstant.STRATEGY_RELATE 同时设置 refResource 为 write_db。这样当写库操作过于频繁时读数据的请求会被限流。