Sentinel学习二

简介: 如果我们不对Sentinel的异常提示做自定义,那么此时的提示是非常不详细的。如果做了自定义,就可以看到下面自定义的提示。sentinel提供了@SentinelResource注解帮助我们来实现自定义的熔断限流后的自定义方法处理,可以根据sentinel的aop可以看到处理的example,从而更为清晰的认识sentinel强大的功能。

一、自定义限流效果

如果我们不对Sentinel的异常提示做自定义,那么此时的提示是非常不详细的。

正常情况下的:

image-20230202211907265.png

如果做了自定义,就可以看到下面自定义的异常提示:

image-20230202211733631.png

相关指标数据信息:

image-20230215182210057.png

二、限流aop增强实现方式

因此我们可以看到Sentinel里面是有对Sentinel的增强的。Sentinel基于aop的增强:

image-20230215154423552.png

看到下面的代码中,带有@SentinelResource这个注解。

1.带SentinelResource注解,写好对应的fallback方法进行自定义处理

    @Override

   @SentinelResource(value="hello", fallback="helloFallback")

   publicStringhello(longs) {

       if (s<0) {

           thrownewIllegalArgumentException("invalid arg");

       }

       returnString.format("Hello at %d", s);

   }

   //自定义处理的方法

   publicStringhelloFallback(longs, Throwableex) {

       ex.printStackTrace();

       return"Oops, error occurred at "+s;

   }

可以看到自定义的处理方法helloFallback。

2.采用blockHandler为异常的处理方法,blockHandlerClass为异常处理的类

   @Override

   @SentinelResource(value="test", blockHandler="handleException", blockHandlerClass= {ExceptionUtil.class})

   publicvoidtest() {

       System.out.println("Test");

   }

3.采用自定义的处理方法,同时忽略异常的类

   @Override

   @SentinelResource(value="helloAnother", defaultFallback="defaultFallback",

       exceptionsToIgnore= {IllegalStateException.class})

   publicStringhelloAnother(Stringname) {

       if (name==null||"bad".equals(name)) {

           thrownewIllegalArgumentException("oops");

       }

       if ("foo".equals(name)) {

           thrownewIllegalStateException("oops");

       }

       return"Hello, "+name;

   }

三、执行aop增强的实现

此时我们停下来想一想,如果想要实现对对应的方法进行增强,需要做哪些操作?

  • 1.首先基于注解做切面
  • 2.在切点中拿到originMethod.getAnnotation(SentinelResource.class)拿到带SentinelResource注解的class的请求
  • 3.根据拿到的注解信息去拿当前请求的资源名称和entry类型
  • 4.执行entry请求 entry = SphU.entry(resourceName, resourceType, entryType, pjp.getArgs());处理完成
  • 5.如果当前的处理出现了异常,会根据对应的注解的方法执行处理,匹配异常,如果是block异常,处理异常handleBlockException;如果是Throwable异常,忽略对应的异常,然后执行handleFallback
  • 6.完成处理之后,执行exit操作 entry.exit(1, pjp.getArgs());    

image-20230215160120869.png

可以看到其是基于切面实现的

   @Around("sentinelResourceAnnotationPointcut()")

   publicObjectinvokeResourceWithSentinel(ProceedingJoinPointpjp) throwsThrowable {

       MethodoriginMethod=resolveMethod(pjp);

       SentinelResourceannotation=originMethod.getAnnotation(SentinelResource.class);

       // 获取资源信息

       StringresourceName=getResourceName(annotation.value(), originMethod);

       EntryTypeentryType=annotation.entryType();

       intresourceType=annotation.resourceType();

       Entryentry=null;

       try {

           // 执行entry

           entry=SphU.entry(resourceName, resourceType, entryType, pjp.getArgs());

           returnpjp.proceed();

       } catch (BlockExceptionex) {

           returnhandleBlockException(pjp, annotation, ex);

       } catch (Throwableex) {

           Class<?extendsThrowable>[] exceptionsToIgnore=annotation.exceptionsToIgnore();

           // The ignore list will be checked first.

           if (exceptionsToIgnore.length>0&&exceptionBelongsTo(ex, exceptionsToIgnore)) {

               throwex;

           }

           if (exceptionBelongsTo(ex, annotation.exceptionsToTrace())) {

               traceException(ex);

               returnhandleFallback(pjp, annotation, ex);

           }

           // No fallback function can handle the exception, so throw it out.

           throwex;

       } finally {

           if (entry!=null) {

               entry.exit(1, pjp.getArgs());

           }

       }

   }

debug进去,可以看到切面中相关注解信息annotation:

@com.alibaba.csp.sentinel.annotation.SentinelResource(blockHandler=handleException, entryType=OUT, fallbackClass=[], exceptionsToIgnore=[], exceptionsToTrace=[classjava.lang.Throwable], defaultFallback=, value=test, fallback=, blockHandlerClass=[classcom.alibaba.csp.sentinel.demo.annotation.aop.service.ExceptionUtil], resourceType=0)

我们可以看到里面有我们熟悉的两个重要方法:

SphU.entry

entry.exit

entry=SphU.entry(resourceName, resourceType, entryType, pjp.getArgs());

entry.exit(1, pjp.getArgs())

可以看到entry操作首先是拿上下文的信息,执行处理链操作,这个过程中会涉及到spi的加载,加载对应的Slot,形成sentinel的责任链骨架。有了这个骨架就可执行对应的责任链的操作了,也即执行entry操作。

Contextcontext=ContextUtil.getContext();

ProcessorSlot<Object>chain=lookProcessChain(resourceWrapper);

Entrye=newCtEntry(resourceWrapper, chain, context);

chain.entry(context, resourceWrapper, null, count, prioritized, args);

可以看到对应的责任链操作:

spi形成对应的Slot之后,放入到map中,执行entry操作,形成责任链模式。这个流程的操作是按照下面这个顺序执行的:

984e9344fc97b66d32c7e94f8186626.png

我们之所以能够看到界面上的数据,那么需要统计之后,才会在界面上显示,因此StatisticSlot的子类DefaultNode里面进行了统计数据操作。

com.alibaba.csp.sentinel.slots.statistic.StatisticSlot#entry

统计的数据信息在这里可以看到会添加到node中,最终node的数据会设置到上下文context中。

四、相关校验规则check

1.白名单认证check

com.alibaba.csp.sentinel.slots.block.authority.AuthoritySlot#entry

checkBlackWhiteAuthority(resourceWrapper, context);

2.系统自适应check

com.alibaba.csp.sentinel.slots.system.SystemSlot#entry

SystemRuleManager.checkSystem(resourceWrapper, count);

3.限流check

com.alibaba.csp.sentinel.slots.block.flow.FlowSlot#entry

checkFlow(resourceWrapper, context, node, count, prioritized);

4.降级隔离check

com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot#entry

performChecking(context, resourceWrapper);

在限流中,check的过程中,会首先会根据对应的规则和策略拿到rule=>Node selectedNode = selectNodeByRequesterAndStrategy(rule, context, node);,通过ruleManager拿到。拿到之后,和通过当前拿到的数据信息和内存中的数据对比,从而判断是是否pass。

限流的接口:

com.alibaba.csp.sentinel.slots.block.flow.TrafficShapingController#canPass(com.alibaba.csp.sentinel.node.Node, int, boolean)

可以看到限流的方式有四种:

Default 默认限流方式,快速失败限流

RateLimiter 匀速限流

WarmUp 冷启动限流

WarmUpRateLimiter 冷启动匀速限流

限流涉及到滑动窗口的知识和相关限流的算法。

执行完成之后,就可执行exit操作了。


目录
相关文章
|
3月前
|
算法 网络协议 安全
深入理解Sentinel系列-1.初识Sentinel
深入理解Sentinel系列-1.初识Sentinel
130 1
深入理解Sentinel系列-1.初识Sentinel
|
3月前
|
存储 监控 测试技术
深入理解Sentinel系列-2.Sentinel原理及核心源码分析(上)
深入理解Sentinel系列-2.Sentinel原理及核心源码分析
75 0
|
3月前
|
监控 BI Sentinel
深入理解Sentinel系列-2.Sentinel原理及核心源码分析(下)
深入理解Sentinel系列-2.Sentinel原理及核心源码分析
44 0
|
8月前
|
监控 Dubbo Java
Sentinel介绍及搭建
Sentinel介绍及搭建
237 0
|
8月前
|
监控 Java 应用服务中间件
sentinel简介
sentinel简介
127 0
|
10月前
|
SpringCloudAlibaba 运维 监控
详解sentinel使用
1.概述 sentinel,springcloud alibaba中对标springcloud Netflix中的hystrix的组件,是一个强大的分布式系统保护工具,通过流量控制、熔断降级和系统负载保护等机制,保障了微服务架构的稳定性和可用性。它是Spring Cloud生态系统中的重要组件之一,被广泛应用于微服务开发和运维中。阿里每年的“双十一”,sentinel就是提供分布式保护机制的核心组件之一。
425 0
|
11月前
|
监控 Java API
Sentinel
Sentinel
|
监控 Java Linux
Sentinel的使用笔记
Sentinel的使用笔记
226 0
Sentinel的使用笔记
|
监控 Dubbo Java
【Sentinel】初识Sentinel
【Sentinel】初识Sentinel
314 0
【Sentinel】初识Sentinel
|
监控 Dubbo Java
Sentinel 使用入门|学习笔记
快速学习 Sentinel 使用入门
126 0
Sentinel 使用入门|学习笔记