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

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

本文主要研究一下sentinel的DegradeSlot

DegradeSlot

com/alibaba/csp/sentinel/slots/block/degrade/DegradeSlot.java

public class DegradeSlot extends AbstractLinkedProcessorSlot
{ @Override public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, Object... args) throws Throwable { DegradeRuleManager.checkDegrade(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); }}
  • 调用DegradeRuleManager.checkDegrade进行降级规则检测

DegradeRuleManager

com/alibaba/csp/sentinel/slots/block/degrade/DegradeRuleManager.java

public class DegradeRuleManager {    private static volatile Map
> degradeRules = new ConcurrentHashMap
>(); final static RulePropertyListener listener = new RulePropertyListener(); private static SentinelProperty
> currentProperty = new DynamicSentinelProperty
>(); static { currentProperty.addListener(listener); } /** * Listen to the {@link SentinelProperty} for {@link DegradeRule}s. The property is the source * of {@link DegradeRule}s. Degrade rules can also be set by {@link #loadRules(List)} directly. * * @param property the property to listen. */ public static void register2Property(SentinelProperty
> property) { synchronized (listener) { currentProperty.removeListener(listener); property.addListener(listener); currentProperty = property; } } public static void checkDegrade(ResourceWrapper resource, Context context, DefaultNode node, int count) throws BlockException { if (degradeRules == null) { return; } List
rules = degradeRules.get(resource.getName()); if (rules == null) { return; } for (DegradeRule rule : rules) { if (!rule.passCheck(context, node, count)) { throw new DegradeException(rule.getLimitApp()); } } } //......}
  • checkDegrade根据资源名称获取对应的降级规则,然后挨个遍历检查

DegradeRule

com/alibaba/csp/sentinel/slots/block/degrade/DegradeRule.java

/** * 

* Degrade is used when the resources are in an unstable state, these resources * will be degraded within the next defined time window. There are two ways to * measure whether a resource is stable or not: *

*
    *
  • * Average response time ({@code DEGRADE_GRADE_RT}): When * the average RT exceeds the threshold ('count' in 'DegradeRule', in milliseconds), the * resource enters a quasi-degraded state. If the RT of next coming 5 * requests still exceed this threshold, this resource will be downgraded, which * means that in the next time window (defined in 'timeWindow', in seconds) all the * access to this resource will be blocked. *
  • *
  • * Exception ratio: When the ratio of exception count per second and the * success qps exceeds the threshold, access to the resource will be blocked in * the coming window. *
  • *
* * @author jialiang.linjl */public class DegradeRule extends AbstractRule { private static final int RT_MAX_EXCEED_N = 5; private static ScheduledExecutorService pool = Executors.newScheduledThreadPool( Runtime.getRuntime().availableProcessors(), new NamedThreadFactory("sentinel-degrade-reset-task", true)); /** * RT threshold or exception ratio threshold count. */ private double count; /** * Degrade recover timeout (in seconds) when degradation occurs. */ private int timeWindow; /** * Degrade strategy (0: average RT, 1: exception ratio). */ private int grade = RuleConstant.DEGRADE_GRADE_RT; private volatile boolean cut = false; public int getGrade() { return grade; } public void setGrade(int grade) { this.grade = grade; } private AtomicLong passCount = new AtomicLong(0); private final Object lock = new Object(); //...... @Override public boolean passCheck(Context context, DefaultNode node, int acquireCount, Object... args) { if (cut) { return false; } ClusterNode clusterNode = ClusterBuilderSlot.getClusterNode(this.getResource()); if (clusterNode == null) { return true; } if (grade == RuleConstant.DEGRADE_GRADE_RT) { double rt = clusterNode.avgRt(); if (rt < this.count) { passCount.set(0); return true; } // Sentinel will degrade the service only if count exceeds. if (passCount.incrementAndGet() < RT_MAX_EXCEED_N) { return true; } } else { double exception = clusterNode.exceptionQps(); double success = clusterNode.successQps(); long total = clusterNode.totalQps(); // if total qps less than RT_MAX_EXCEED_N, pass. if (total < RT_MAX_EXCEED_N) { return true; } if (success == 0) { return exception < RT_MAX_EXCEED_N; } if (exception / (success + exception) < count) { return true; } } synchronized (lock) { if (!cut) { // Automatically degrade. cut = true; ResetTask resetTask = new ResetTask(this); pool.schedule(resetTask, timeWindow, TimeUnit.SECONDS); } return false; } } //...... private static final class ResetTask implements Runnable { private DegradeRule rule; ResetTask(DegradeRule rule) { this.rule = rule; } @Override public void run() { rule.getPassCount().set(0); rule.setCut(false); } }}
  • 这个passCheck根据平均响应时间以及异常个数等进行降级判断
  • 触发降级时标志cut为true,然后启动一个ResetTask,在指定时间窗口之后重置cut为false并清空passCount计数

小结

sentinel的DegradeSlot主要依据平均响应时间以及异常次数来判断,进入降级模式时启动定时任务在指定时间窗口重置相关计数,恢复到正常模式。

doc

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

你可能感兴趣的文章
移动互联网下半场,iOS开发者如何“高薪”成长?
查看>>
Atlassian是怎样进行持续交付的?且听 Steve Smith一一道来
查看>>
Web Storage相关
查看>>
[PHP内核探索]PHP中的哈希表
查看>>
Apache-drill Architechture
查看>>
WordPress 5.2 Beta 3 发布,要求 PHP 5.6.20 以上版本
查看>>
通通连起来——无处不在的流
查看>>
互联网+时代,看云计算如何改变传统行业
查看>>
ZFS ARC & L2ARC zfs-$ver/module/zfs/arc.c
查看>>
c++类默认拷贝构造函数---浅复制
查看>>
2019年最火热的Golang项目
查看>>
可实现RSSD云硬盘120万IOPS的SPDK IO路径优化实践
查看>>
Vue项目部署遇到的坑(你肯定会遇到!)
查看>>
资源分享计划第三期 0511
查看>>
awk 文本处理
查看>>
【JSConf EU 2018】主题总结 (部分主题已有中文文章)
查看>>
JavaScript面向对象名词详解
查看>>
Java设计模式学习 - 责任链模式
查看>>
JVM,DVM,ART
查看>>
webgl滤镜--会呼吸的痛
查看>>