博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊聊sentinel的FlowSlot
阅读量:6433 次
发布时间:2019-06-23

本文共 7109 字,大约阅读时间需要 23 分钟。

本文主要研究一下sentinel的FlowSlot

FlowSlot

com/alibaba/csp/sentinel/slots/block/flow/FlowSlot.java

public class FlowSlot extends AbstractLinkedProcessorSlot
{ @Override public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, Object... args) throws Throwable { FlowRuleManager.checkFlow(resourceWrapper, context, node, count); fireEntry(context, resourceWrapper, node, count, args); } @Override public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) { fireExit(context, resourceWrapper, count, args); }}

FlowRuleManager.checkFlow

com/alibaba/csp/sentinel/slots/block/flow/FlowRuleManager.java

public static void checkFlow(ResourceWrapper resource, Context context, DefaultNode node, int count)        throws BlockException {        List
rules = flowRules.get(resource.getName()); if (rules != null) { for (FlowRule rule : rules) { if (!rule.passCheck(context, node, count)) { throw new FlowException(rule.getLimitApp()); } } } }
  • 这里调用FlowRule的passCheck方法

FlowRule

com/alibaba/csp/sentinel/slots/block/flow/FlowRule.java

/*** * 

* Each flow rule is mainly composed of three factors: grade, * strategy and controlBehavior. *

*
    *
  • The {@link #grade} represents the threshold type of flow control (by QPS or thread count).
  • *
  • The {@link #strategy} represents the strategy based on invocation relation.
  • *
  • The {@link #controlBehavior} represents the QPS shaping behavior (actions on incoming request when QPS * exceeds the threshold).
  • *
* * @author jialiang.linjl * @author Eric Zhao */public class FlowRule extends AbstractRule { public static final String LIMIT_APP_DEFAULT = "default"; public static final String LIMIT_APP_OTHER = "other"; public FlowRule(){ super(); setLimitApp(LIMIT_APP_DEFAULT); } /** * The threshold type of flow control (0: thread count, 1: QPS). */ private int grade = RuleConstant.FLOW_GRADE_QPS; /** * Flow control threshold count. */ private double count; /** * Flow control strategy based on invocation chain. * * {@link RuleConstant#STRATEGY_DIRECT} for direct flow control (by origin); * {@link RuleConstant#STRATEGY_RELATE} for relevant flow control (with relevant resource); * {@link RuleConstant#STRATEGY_CHAIN} for chain flow control (by entrance resource). */ private int strategy = RuleConstant.STRATEGY_DIRECT; /** * Reference resource in flow control with relevant resource. */ private String refResource; /** * Rate limiter control behavior. * 0. default, 1. warm up, 2. rate limiter */ private int controlBehavior = RuleConstant.CONTROL_BEHAVIOR_DEFAULT; private int warmUpPeriodSec = 10; /** * Max queueing time in rate limiter behavior. */ private int maxQueueingTimeMs = 500; private Controller controller; //...... @Override public boolean passCheck(Context context, DefaultNode node, int acquireCount, Object... args) { String limitApp = this.getLimitApp(); if (limitApp == null) { return true; } String origin = context.getOrigin(); Node selectedNode = selectNodeByRequesterAndStrategy(origin, context, node); if (selectedNode == null) { return true; } return controller.canPass(selectedNode, acquireCount); } private Node selectNodeByRequesterAndStrategy(String origin, Context context, DefaultNode node) { // The limit app should not be empty. String limitApp = this.getLimitApp(); if (limitApp.equals(origin)) { if (strategy == RuleConstant.STRATEGY_DIRECT) { return context.getOriginNode(); } String refResource = this.getRefResource(); if (StringUtil.isEmpty(refResource)) { return null; } if (strategy == RuleConstant.STRATEGY_RELATE) { return ClusterBuilderSlot.getClusterNode(refResource); } if (strategy == RuleConstant.STRATEGY_CHAIN) { if (!refResource.equals(context.getName())) { return null; } return node; } } else if (LIMIT_APP_DEFAULT.equals(limitApp)) { if (strategy == RuleConstant.STRATEGY_DIRECT) { return node.getClusterNode(); } String refResource = this.getRefResource(); if (StringUtil.isEmpty(refResource)) { return null; } if (strategy == RuleConstant.STRATEGY_RELATE) { return ClusterBuilderSlot.getClusterNode(refResource); } if (strategy == RuleConstant.STRATEGY_CHAIN) { if (!refResource.equals(context.getName())) { return null; } return node; } } else if (LIMIT_APP_OTHER.equals(limitApp) && FlowRuleManager.isOtherOrigin(origin, getResource())) { if (strategy == RuleConstant.STRATEGY_DIRECT) { return context.getOriginNode(); } String refResource = this.getRefResource(); if (StringUtil.isEmpty(refResource)) { return null; } if (strategy == RuleConstant.STRATEGY_RELATE) { return ClusterBuilderSlot.getClusterNode(refResource); } if (strategy == RuleConstant.STRATEGY_CHAIN) { if (!refResource.equals(context.getName())) { return null; } if (node != null) { return node; } } } return null; } //......}
  • 这里首先通过selectNodeByRequesterAndStrategy查找对应的node
  • 之后调用controller.canPass进行限流判断,controller根据不同参数有不同实现类,默认是DefaultController,其余两个为PaceController、WarmUpController
  • controlBehavior有3种,分别是RuleConstant.CONTROL_BEHAVIOR_DEFAULT,直接拒绝;RuleConstant.CONTROL_BEHAVIOR_WARM_UP,冷启动;RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER,均速器。

DefaultController

com/alibaba/csp/sentinel/slots/block/flow/controller/DefaultController.java

public class DefaultController implements Controller {    double count = 0;    int grade = 0;    public DefaultController(double count, int grade) {        super();        this.count = count;        this.grade = grade;    }    @Override    public boolean canPass(Node node, int acquireCount) {        int curCount = avgUsedTokens(node);        if (curCount + acquireCount > count) {            return false;        }        return true;    }    private int avgUsedTokens(Node node) {        if (node == null) {            return -1;        }        return grade == RuleConstant.FLOW_GRADE_THREAD ? node.curThreadNum() : (int)node.passQps();    }}
  • 默认主要是依据当前node的线程数或qps来判断

小结

  • sentinel的FlowSlot的默认的限流方式有两个维度,一个是基于线程数,一个是基于qps
  • 基于qps的还有其他两种限流策略,一种是冷启动,一个是匀速器
  • 冷启动适用于需要时间准备资源的请求,匀速器则控制请求以均匀的速度通过

doc

转载地址:http://drxga.baihongyu.com/

你可能感兴趣的文章
入门视频采集与处理(BT656简介) 转
查看>>
Unity GUI选择与评价
查看>>
PHP于DIRECTORY_SEPARATOR任务
查看>>
c++ 时间与字符串转换
查看>>
SDE ST_Geometry SQL st_intersects查询很慢的解决方法
查看>>
Faster-rnnlm代码分析2 - HSTree的构造
查看>>
Strategic Game(匈牙利算法,最小点覆盖数)
查看>>
如何通过REST获取JENKINS的编译进度?
查看>>
HBase目录
查看>>
AngularJs $q 承诺与延迟
查看>>
用Castor 处理XML文档
查看>>
命名管道跨进程通信实例1(转)
查看>>
8个超有用的Java測试工具和框架
查看>>
Mysql对自增主键ID进行重新排序
查看>>
[原创]浅谈互联网金融理财系统测试
查看>>
tcp/ip协议listen函数中backlog參数的含义
查看>>
apache开源项目--kafka
查看>>
软考之操作系统
查看>>
Selenium (3) —— Selenium IDE + Firefox录制登录脚本(101 Tutorial)
查看>>
[ACM] hdu 4405 Aeroplane chess (概率DP)
查看>>