slot 游戏源码-深入解析微服务高并发热点参数限流:热点参数限流功能的实现

热点参数限流

参数限流是指根据方法传递的参数进行限流,或者根据socket请求的参数进行限流,而热参数限流是指对经常访问的参数进行限流。

在电子商务场景中,每个客户购买不同的产品。 有主播带货的产品订单流量较大,无主播的产品订单流量相对较少。 由于产品数量有限slot 游戏源码,不可能每个订单请求都能成功。 因此,如果我们能够根据客户端请求传递的商品ID来实现限流,将流量控制在商品总库存左右,并采用QPS限流等方式slot 游戏源码,通过做口袋,通过socket的有效流量可以最大化。

本文的内容主要包括以下几个方面。

实现热点参数限流功能。

流量功效控制。

热点参数限流功能的实现

与基于资源的限流不同,热点参数限流是基于资源参数的不同取值。 不需要统计资源指标数据,但需要统计不同参数值的指标数据。 因此,热点参数限流功能并不在Sentinel的核心模块中,而是作为一个扩展功能,放在Sentinel的扩展功能模块——sentinelextension中,其子模块是sentinel-parameter-flow-control。

热点参数指标数据统计

热点参数限流不使用Node统计指标数据,而是使用ParameterMetric和ParameterMetricStorage统计指标数据。

ParameterMetric:用于实现类似ClusterNode的统计功能。

ParameterMetricStorage:用于实现类似EntranceNode的功能,管理并存储各个资源对应的ParameterMetric。

ParameterMetric有3个静态数组,源码如下。

ruleTimeCounters:用于达到统一流量控制的效果。 关键是参数限流规则(ParamFlowRule),数值是该参数不同值对应的之前的代币生产时间。

ruleTokenCounter:用于达到统一流控的效果。 key是参数限流规则(ParamFlowRule),value是参数不同值对应的当前令牌桶中的令牌数量。

threadCountMap:key为参数索引,value为不同参数值对应的当前并行占用的线程总数。

ParameterMetricStorage使用ConcurrentHashMap来缓存每个资源对应的ParameterMetric,并且只会为配置了参数限流规则的资源创建一个ParameterMetric实例。 其部分源代码如下。

ParameterMetricStorage 的 initParamMetricsFor 方法用于创建和初始化资源的 ParameterMetric 实例。 该方法在访问资源时由ParamFlowSlot调用,并且只有在为资源配置了参数限流规则时才会调用该方法。

slot 游戏源码-深入解析微服务高并发热点参数限流:热点参数限流功能的实现

热点参数限流实现原理

既然是参数限流,那么就必须获取参数,而ProcessorSlot#entry方法的最后一个参数就是请求传递的参数,通过SphU#entry方法逐层向上传递。

回顾一下Sentinel的用例,代码如下。

这种情况下,如果导出了热点参数限流模块,并且为资源GET配置了热点参数规则:/hello,则调用SphU#entry方法时传入的名称就是热点参数,最终会传入该名称到热点。 参数限流模块的ProcessorSlot。

热点参数限流模块通过JavaSPI注册一个定制的SlotChainBuilder,即注册HotParamSlotChainBuilder,并将ParamFlowSlot放在StatisticSlot旁边。 这个ParamFlowSlot就是实现热点参数限流功能的处理器socket。 其部分源代码如下。

如源码所示,在ParamFlowSlot#entry方法中,首先调用ParamFlowRuleManager#hasRules方法判断当前资源是否存在参数限流规则。 如果存在,则调用ParamFlowSlot#checkFlow方法判断是否允许当前请求通过。 ParamFlowSlot#checkFlow方法的源码如下。

slot 游戏源码-深入解析微服务高并发热点参数限流:热点参数限流功能的实现

① checkFlow方法的最后一个参数是请求参数,即调用SphU#entry方法传入的参数。 如果参数为空,则无需执行后续逻辑。

② 调用ParamFlowRuleManager#getRulesOfResource获取当前资源配置的所有参数

限流规则。

③遍历参数限流规则,首先调用ParameterMetricStorage#initParamMetricsFor方法判断是否需要创建ParameterMetric实例用于当前资源初始化,然后调用ParamFlowChecker#passCheck方法判断是否可以释放当前请求。 如果需要拒绝请求,则会抛出 ParamFlowException。

在阅读ParamFlowChecker#passCheck方法源码之前,我们需要先了解一下参数限流规则的配置,了解各个配置项的作用。

设置参数限流规则的类名为ParamFlowRule,其源码如下。

Grade:限流规则的阈值类型。 支持的类型与FlowRule相同。

count:阈值,支持的类型与FlowRule相同。

slot 游戏源码-深入解析微服务高并发热点参数限流:热点参数限流功能的实现

paramIdx:参数索引。 ParamFlowChecker根据限流规则的参数索引获取参数的值。 下标从0开始。例如apiHello(String name)方法只有一个参数,name参数对应的索引为0。

controlBehavior:流控效果,支持的类型与FlowRule相同,但只支持快速失败和统一排队。

maxQueueingTimeMs:虚拟队列的最大等待时间,以达到统一排队流控的效果。 超过该值的请求将被丢弃。 支持的类型与FlowRule相同。

urationInSec:统计指标数据的时间窗口大小,单位为秒。

burstCount:支持的突发流量总量。

假设需要对资源GET:/hello的name参数进行限流,当name值为jackson,QPS限流阈值为5时,代码如下。

以此为例,我们继续分析ParamFlowChecker#passCheck方法的源码。 passCheck 方法返回 true 表示通过,返回 false 表示拒绝。 passCheck方法的源码如下。

slot 游戏源码-深入解析微服务高并发热点参数限流:热点参数限流功能的实现

① 如果参数为空,或者规则配置的参数索引越界,或者参数索引对应的参数值为空,则释放请求。

② 如果是集群限流模式,则调用passClusterCheck方法,否则调用passLocalCheck方法。

我们先不讨论集群限流情况,只看单机本地限流情况。 passLocalCheck方法的源码如下。

由于参数可能是基本数据类型,也可能是链表类型、引用类型,所以passLocalCheck方法分为三种情况进行处理。 这里仅讨论其中一种情况,其他情况的治疗方法类似。

以资源GET:/hello为例,apiHello方法的name参数是String类型,所以会调用passSingleValueCheck方法。 该技术的源代码如下。

① 当规则配置的阈值类型为QPS时,根据限流的效果,调用passThrottleLocalCheck方法或passDefaultLocalCheck方法。

② 当规则配置的阈值类型为Threads时,获取当前资源的ParameterMetric实例即可获取当前资源对应的并行占用线程总数及参数值。 如果并发占用线程总数加1小于限流阈值,则拒绝该请求,否则释放该请求。

并行占用线程总数在哪里增加和减少? 这是由两个回调 ParamFlowStatisticEntryCallback 和 ParamFlowStatisticExitCallback 实现的。 这两个Callback分别在StatisticSlot的进入模式和退出模式下被反弹执行。

本文给大家讲解的是微服务高并发热点参数限流的深入解析:热点参数限流功能的实现

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 游戏源码 slot 游戏源码-深入解析微服务高并发热点参数限流:热点参数限流功能的实现 https://www.wkzy.net/game/184146.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务