SentinelInvocationHandler
作用于远程调用
可以看到就是用了代理模式
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class SentinelInvocationHandler implements InvocationHandler { private final Target<?> target; private final Map<Method, MethodHandler> dispatch; private FallbackFactory fallbackFactory; private Map<Method, Method> fallbackMethodMap; SentinelInvocationHandler(Target<?> target, Map<Method, MethodHandler> dispatch, FallbackFactory fallbackFactory) { this.target = checkNotNull(target, "target"); this.dispatch = checkNotNull(dispatch, "dispatch"); this.fallbackFactory = fallbackFactory; this.fallbackMethodMap = toFallbackMethod(dispatch); } SentinelInvocationHandler(Target<?> target, Map<Method, MethodHandler> dispatch) { this.target = checkNotNull(target, "target"); this.dispatch = checkNotNull(dispatch, "dispatch"); }
1.执行前SphU.entry,sentinel特定逻辑
2.invoke方法
3.异常判断fallbackFactory不为空,则调用fallback方法,否则直接抛异常
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83@Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { if ("equals".equals(method.getName())) { try { Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null; return equals(otherHandler); } catch (IllegalArgumentException e) { return false; } } else if ("hashCode".equals(method.getName())) { return hashCode(); } else if ("toString".equals(method.getName())) { return toString(); } Object result; MethodHandler methodHandler = this.dispatch.get(method); // only handle by HardCodedTarget if (target instanceof Target.HardCodedTarget) { Target.HardCodedTarget hardCodedTarget = (Target.HardCodedTarget) target; MethodMetadata methodMetadata = SentinelContractHolder.METADATA_MAP .get(hardCodedTarget.type().getName() + Feign.configKey(hardCodedTarget.type(), method)); // resource default is HttpMethod:protocol://url if (methodMetadata == null) { result = methodHandler.invoke(args); } else { String resourceName = methodMetadata.template().method().toUpperCase() + ":" + hardCodedTarget.url() + methodMetadata.template().path(); Entry entry = null; try { ContextUtil.enter(resourceName); entry = SphU.entry(resourceName, EntryType.OUT, 1, args); result = methodHandler.invoke(args); } catch (Throwable ex) { // fallback handle if (!BlockException.isBlockException(ex)) { Tracer.trace(ex); } if (fallbackFactory != null) { try { Object fallbackResult = fallbackMethodMap.get(method) .invoke(fallbackFactory.create(ex), args); return fallbackResult; } catch (IllegalAccessException e) { // shouldn't happen as method is public due to being an // interface throw new AssertionError(e); } catch (InvocationTargetException e) { throw new AssertionError(e.getCause()); } } else { // throw exception if fallbackFactory is null throw ex; } } finally { if (entry != null) { entry.exit(1, args); } ContextUtil.exit(); } } } else { // other target type using default strategy result = methodHandler.invoke(args); } return result; }
SentinelResourceAspect
作用于controller上的方法
sentinel自引入了一个切面类(基于注解@SentinelResource),若有异常会进入定义的
fallback方法
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47@Aspect public class SentinelResourceAspect extends AbstractSentinelAspectSupport { @Pointcut("@annotation(com.alibaba.csp.sentinel.annotation.SentinelResource)") public void sentinelResourceAnnotationPointcut() { } @Around("sentinelResourceAnnotationPointcut()") public Object invokeResourceWithSentinel(ProceedingJoinPoint pjp) throws Throwable { Method originMethod = resolveMethod(pjp); SentinelResource annotation = originMethod.getAnnotation(SentinelResource.class); if (annotation == null) { // Should not go through here. throw new IllegalStateException("Wrong state for SentinelResource annotation"); } String resourceName = getResourceName(annotation.value(), originMethod); EntryType entryType = annotation.entryType(); int resourceType = annotation.resourceType(); Entry entry = null; try { entry = SphU.entry(resourceName, resourceType, entryType, pjp.getArgs()); Object result = pjp.proceed(); return result; } catch (BlockException ex) { return handleBlockException(pjp, annotation, ex); } catch (Throwable ex) { Class<? extends Throwable>[] exceptionsToIgnore = annotation.exceptionsToIgnore(); // The ignore list will be checked first. if (exceptionsToIgnore.length > 0 && exceptionBelongsTo(ex, exceptionsToIgnore)) { throw ex; } if (exceptionBelongsTo(ex, annotation.exceptionsToTrace())) { traceException(ex, annotation); return handleFallback(pjp, annotation, ex); } // No fallback function can handle the exception, so throw it out. throw ex; } finally { if (entry != null) { entry.exit(1, pjp.getArgs()); } } } }
最后
以上就是腼腆蓝天最近收集整理的关于Sentinel限流逻辑的全部内容,更多相关Sentinel限流逻辑内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复