4.Sentinel源码分析— Sentinel是如何做到降级的?
各位中秋节快乐啊,我觉得在这个月圆之夜有必要写一篇源码解析,以表示我内心的高兴~
Sentinel源码解析系列:
1.Sentinel源码分析—FlowRuleManager加载规则做了什么?
2. Sentinel源码分析—Sentinel是如何进行流量统计的?
3. Sentinel源码分析— QPS流量控制是如何实现的?
在我的第二篇文章里面2. Sentinel源码分析—Sentinel是如何进行流量统计的?里面介绍了整个Sentinel的主流程是怎样的。所以降级的大致流程可以概述为:
1. 设置降级策略,是根据平均响应时间还是异常比例来进行降级的
2. 根据资源创建一系列的插槽
3. 依次调用插槽,根据设定的插槽类型来进行降级
我们先来看个例子,方便大家自己断点跟踪:
private static final String KEY = "abc"; private static final int threadCount = 100; private static int seconds = 60 + 40; public static void main(String[] args) throws Exception { List<DegradeRule> rules = new ArrayList<DegradeRule>(); DegradeRule rule = new DegradeRule(); rule.setResource(KEY); // set threshold rt, 10 ms rule.setCount(10); rule.setGrade(RuleConstant.DEGRADE_GRADE_RT); rule.setTimeWindow(10); rules.add(rule); DegradeRuleManager.loadRules(rules); for (int i = 0; i < threadCount; i++) { Thread entryThread = new Thread(new Runnable() { @Override public void run() { while (true) { Entry entry = null; try { TimeUnit.MILLISECONDS.sleep(5); entry = SphU.entry(KEY); // token acquired pass.incrementAndGet(); // sleep 600 ms, as rt TimeUnit.MILLISECONDS.sleep(600); } catch (Exception e) { block.incrementAndGet(); } finally { total.incrementAndGet(); if (entry != null) { entry.exit(); } } } } }); entryThread.setName("working-thread"); entryThread.start(); } }
其他的流程基本上和第二篇文章里介绍的差不多,这篇文章来介绍Sentinel的主流程,Sentinel的降级策略全部都是在DegradeSlot中进行操作的。
DegradeSlot
public class DegradeSlot extends AbstractLinkedProcessorSlot<DefaultNode> { @Override public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, boolean prioritized, Object... args) throws Throwable { DegradeRuleManager.checkDegrade(resourceWrapper, context, node, count); fireEntry(context, resourceWrapper, node, count, prioritized, args); } }
DegradeSlot会直接调用DegradeRuleManager进行降级的操作,我们直接进入到DegradeRuleManager.checkDegrade方法中。
DegradeRuleManager#checkDegrade
public static void checkDegrade(ResourceWrapper resource, Context context, DefaultNode node,