前两篇文章只画了流程图,发现反响不够好,没几个阅读量,今天我把看源码的方式也记录下,详细解析下主线逻辑。
sentinel实现其实就是一个大的Try catch ,在StatisticSlot保存各种指标,在其他slot中进行判断,通过就继续执行其他slot,不能通过就抛出异常,达到阈值就进行限流或者降级操作。
先上一个源码分析的流程图
1. sentinel是通过aop实现的它的注解是@SentinelResource那我们就找他的实现
2. 找到SentinelResourceAspect类的invokeResourceWithSentinel方法就是具体实现。
public Object invokeResourceWithSentinel(ProceedingJoinPoint pjp) throws Throwable { Method originMethod = this.resolveMethod(pjp); SentinelResource annotation = (SentinelResource)originMethod.getAnnotation(SentinelResource.class); if (annotation == null) { throw new IllegalStateException("Wrong state for SentinelResource annotation"); } else { String resourceName = this.getResourceName(annotation.value(), originMethod); EntryType entryType = annotation.entryType(); int resourceType = annotation.resourceType(); Entry entry = null; try { Object var18; try { entry = SphU.entry(resourceName, resourceType, entryType, pjp.getArgs()); Object result = pjp.proceed(); var18 = result; return var18; } catch (BlockException var15) { var18 = this.handleBlockException(pjp, annotation, var15); return var18; } catch (Throwable var16) { Class<? extends Throwable>[] exceptionsToIgnore = annotation.exceptionsToIgnore(); if (exceptionsToIgnore.length > 0 && this.exceptionBelongsTo(var16, exceptionsToIgnore)) { throw var16; } else if (this.exceptionBelongsTo(var16, annotation.exceptionsToTrace())) { this.traceException(var16, annotation); Object var10 = this.handleFallback(pjp, annotation, var16); return var10; } else { throw var16; } } } finally { if (entry != null) { entry.exit(1, pjp.getArgs()); } } } }
3 调用SphU.entry方法,一步步跟到具体实现,找到CtSph类的entryWithPriority方法。
获取slot的方法。
ProcessorSlot<Object> chain = lookProcessChain(resourceWrapper);
ProcessorSlot<Object> lookProcessChain(ResourceWrapper resourceWrapper) { ProcessorSlotChain chain = chainMap.get(resourceWrapper); if (chain == null) { synchronized (LOCK) { chain = chainMap.get(resourceWrapper); if (chain == null) { // Entry size limit. if (chainMap.size() >= Const