2. Sentinel源码分析—Sentinel是如何进行流量统计的? (5)

FlowRuleChecker#canPassCheck

public boolean canPassCheck(/*@NonNull*/ FlowRule rule, Context context, DefaultNode node, int acquireCount, boolean prioritized) { //如果没有设置limitapp,那么不进行校验,默认会给个defualt String limitApp = rule.getLimitApp(); if (limitApp == null) { return true; } //集群模式 if (rule.isClusterMode()) { return passClusterCheck(rule, context, node, acquireCount, prioritized); } //本地模式 return passLocalCheck(rule, context, node, acquireCount, prioritized); }

这个方法首先会校验limitApp,然后判断是集群模式还是本地模式,我们这里暂时分析本地模式。

FlowRuleChecker#passLocalCheck

private static boolean passLocalCheck(FlowRule rule, Context context, DefaultNode node, int acquireCount, boolean prioritized) { //节点选择 Node selectedNode = selectNodeByRequesterAndStrategy(rule, context, node); if (selectedNode == null) { return true; } //根据设置的规则来拦截 return rule.getRater().canPass(selectedNode, acquireCount, prioritized); }

本地模式中,首先会调用selectNodeByRequesterAndStrategy进行节点选择,根据不同的模式选择不同的节点,然后调用规则控制器的canPass方法进行拦截。

FlowRuleChecker#selectNodeByRequesterAndStrategy

static Node selectNodeByRequesterAndStrategy(/*@NonNull*/ FlowRule rule, Context context, DefaultNode node) { // The limit app should not be empty. String limitApp = rule.getLimitApp(); //关系限流策略 int strategy = rule.getStrategy(); String origin = context.getOrigin(); //origin不为`default` or `other`,并且limitApp和origin相等 if (limitApp.equals(origin) && filterOrigin(origin)) {//1 if (strategy == RuleConstant.STRATEGY_DIRECT) { // Matches limit origin, return origin statistic node. return context.getOriginNode(); } //关系限流策略为关联或者链路的处理 return selectReferenceNode(rule, context, node); } else if (RuleConstant.LIMIT_APP_DEFAULT.equals(limitApp)) {//2 if (strategy == RuleConstant.STRATEGY_DIRECT) { //这里返回ClusterNode,表示所有应用对该资源的所有请求情况 // Return the cluster node. return node.getClusterNode(); } //关系限流策略为关联或者链路的处理 return selectReferenceNode(rule, context, node); } else if (RuleConstant.LIMIT_APP_OTHER.equals(limitApp) && FlowRuleManager.isOtherOrigin(origin, rule.getResource())) {//3 if (strategy == RuleConstant.STRATEGY_DIRECT) { return context.getOriginNode(); } //关系限流策略为关联或者链路的处理 return selectReferenceNode(rule, context, node); } return null; }

这个方法主要是用来根据控制根据不同的规则,获取不同的node进行数据的统计。

在标记1中表示,如果流控规则配置了来源应用且不是"default"或者"other"这种特殊值,那么这种时候该规则就只对配置的来源应用生效。

在标记2中表示,limitApp是"default",代表针对所有应用进行统计。

标记7中,这个是"other"值的处理,假设当前请求来源不在当前规则的limitApp中,则进行下面的处理。

我这里引用官方文档的一段话进行解释:

default:表示不区分调用者,来自任何调用者的请求都将进行限流统计。如果这个资源名的调用总和超过了这条规则定义的阈值,则触发限流。 {some_origin_name}:表示针对特定的调用者,只有来自这个调用者的请求才会进行流量控制。例如 NodeA 配置了一条针对调用者caller1的规则,那么当且仅当来自 caller1 对 NodeA 的请求才会触发流量控制。 other:表示针对除 {some_origin_name} 以外的其余调用方的流量进行流量控制。例如,资源NodeA配置了一条针对调用者 caller1 的限流规则,同时又配置了一条调用者为 other 的规则,那么任意来自非 caller1 对 NodeA 的调用,都不能超过 other 这条规则定义的阈值 同一个资源名可以配置多条规则,规则的生效顺序为:{some_origin_name} > other > default

然后返回到passLocalCheck方法中,继续往下走,调用rule.getRater(),我们这里没有指定特殊的rater,所以返回的是DefaultController。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwfdp.html