• 【微服务|Sentinel】SentinelResourceAspect详解


    文章目录

    AOP

    上文我们讲到@SentinelResource注解,我们都知道注解只是一种标记,那么真正实现限流逻辑的就是AOP了。

    AOP在实际开发中都会解决哪些业务问题呢?

    1. 事务相关
      用来回滚事物

    2. 性能监控
      在方法调用前后记录调用时间,方法执行太长或超时报警。

    3. 缓存代理
      缓存某方法的返回值,下次执行该方法时,直接从缓存里获取。

    4. 软件破解
      使用AOP修改软件的验证类的判断逻辑。

    5. 记录日志
      在方法执行前后记录系统日志。

    6. 工作流系统
      工作流系统需要将业务代码和流程引擎代码混合在一起执行,那么我们可以使用AOP将其分离,并动态挂接业务。

    7. 权限验证
      方法执行前验证是否有权限执行当前方法,没有则抛出没有权限执行异常,由业务代码捕捉。

    接下来,我们来看一看它的源码吧
    com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect

    源码

    @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);
                    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());
                }
            }
        }
    }
    
    • 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

    源码分析

    我们来分析一下这块的代码:

    1. 使用aspect的around拦截,拦截标注有SentinelResource的注解
    2. 进入方法之前调用SphU.entry(resourceName, entryType),结束之后调用entry.exit();
    3. 异常的时候调用handleBlockException方法

    这也验证我们前一篇文章,在注解内对异常处理的两种方案。

  • 相关阅读:
    Linux编译器-gcc/g++使用&函数库
    【机械】基于matlab模拟打桩机运动学仿真附matlab代码
    智能巡检系统有什么特点和功能?它是如何推动企业高效管理?
    Verilog 基础知识
    aspnetcore中aop的实现
    卷积神经网络到底是什么,卷积神经网络是一种
    Sentinel使用Nacos存储规则——Gateway网关服务
    从创建神经声音到成功完成PoC
    【数据结构】链表OJ第二篇 —— 链表的中间节点 && 链表中倒数第k个节点 && 链表分割 && 链表的回文结构 && 相交链表
    Windows环境-Redis数据库部署
  • 原文地址:https://blog.csdn.net/CSDN_SAVIOR/article/details/125560670