iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > VUE >Sentinel 流控的原理是什么
  • 183
分享到

Sentinel 流控的原理是什么

2024-04-02 19:04:59 183人浏览 安东尼
摘要

Sentinel 流控的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。@ResoureSetinel 工作原理配置流

Sentinel 流控的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

@ResoureSetinel 工作原理

配置流控规则我们最简单的方式就是通过 @ResoureSetinel  的方式来管理,该注解可以直接定义流控规则、降级规则。下面是一个简单的使用例子:

@SentinelResource(value = "ResOrderGet",                   fallback = "fallback",                   fallbackClass = SentinelResourceExceptionHandler.class,                   blockHandler = "blockHandler",                   blockHandlerClass = SentinelResourceExceptionHandler.class                  ) @GetMapping("/order/get/{id}") public CommonResult<StockModel> getStockDetails(@PathVariable Integer id) {   StockModel stockModel = new StockModel();   stockModel.setCode("STOCK==>1000");   stockModel.setId(id);   return CommonResult.success(stockModel); }

如果大家熟悉 spring 相关的组件大家都可以想到,这里多半是通过Spring aop. 的方式来拦截 getStockDetails  方法。我们先看看SentinelAutoConfiguration 配置文件,我们可以找到 SentinelResourceAspect Bean  的定义方法。

@Bean @ConditionalOnMissingBean public SentinelResourceAspect sentinelResourceAspect() {    return new SentinelResourceAspect(); }

让后我们再来看看 SentinelResourceAspect 具体是怎么处理的,源码如下:

// 定义 Pointcut @Pointcut("@annotation(com.alibaba.csp.sentinel.annotation.SentinelResource)") public void sentinelResourceAnnotationPointcut() { } // Around 来对被标记 @SentinelResource 注解的方法进行处理 @Around("sentinelResourceAnnotationPointcut()") public Object invokeResourceWithSentinel(ProceedingJoinPoint pjp) throws Throwable {   Method originMethod = resolveMethod(pjp);   // 获取注解信息   SentinelResource annotation = originMethod.getAnnotation(SentinelResource.class);   // 获取资源名称   String resourceName = getResourceName(annotation.value(), originMethod);   EntryType entryType = annotation.entryType();   int resourceType = annotation.resourceType();   Entry entry = null;   try {     // 执行 entry     entry = SphU.entry(resourceName, resourceType, entryType, pjp.getArgs());     // 执行业务方法     Object result = pjp.proceed();     // 返回     return result;   } catch (BlockException ex) {     // 处理 BlockException     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;   } }

我们总结一下, @SentinelResource 的执行过程, 首先是通过 Aop 进行拦截,然后通过 SphU.entry  执行对应的流控规则,最后调用业务方法。如果触发流控规则首先处理流控异常 BlockException 然后在判断是否有服务降级的处理,如果有就调用  fallback 方法。通过 handleBlockException 、handleFallback 进行处理。

责任链模式处理流控

通过上面的梳理,我们知道对于流控的过程,核心处理方法就是 SphU.entry 。在这个方法中其实主要就是初始化流控 Solt 和执行 Solt.  在这个过程中会对:簇点定义、流量控制、熔断降级、系统白名单等页面功能进行处理。

1. 初始化责任链

下面是初始化 Solt 的核心代码在 SphU.entryWithPriority

// 删减部分代码 private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args)   throws BlockException {   // 初始化责任链   ProcessorSlot<Object> chain = lookProcessChain(resourceWrapper);   Entry e = new CtEntry(resourceWrapper, chain, context);   try {     // 执行 entry     chain.entry(context, resourceWrapper, null, count, prioritized, args);   } catch (BlockException e1) {     e.exit(count, args);     // 异常抛出,让 SentinelResourceAspect.invokeResourceWithSentinel 统一处理     throw e1;   } catch (Throwable e1) {     // This should not happen, unless there are errors existing in Sentinel internal.     RecordLog.info("Sentinel unexpected exception", e1);   }   return e; }

通过 lookProcessChain 方法我逐步的查找,我们可以看到最终的责任链初始化类,默认是   DefaultSlotChainBuilder

public class DefaultSlotChainBuilder implements SlotChainBuilder {     @Override     public ProcessorSlotChain build() {         ProcessorSlotChain chain = new DefaultProcessorSlotChain();         // Note: the instances of ProcessorSlot should be different, since they are not stateless.         // 通过 SPI 去加载所有的  ProcessorSlot 实现,通过 Order 排序         List<ProcessorSlot> sortedSlotList = SpiLoader.loadPrototypeInstanceListSorted(ProcessorSlot.class);         for (ProcessorSlot slot : sortedSlotList) {             if (!(slot instanceof AbstractLinkedProcessorSlot)) {                 RecordLog.warn("The ProcessorSlot(" + slot.getClass().getCanonicalName() + ") is not an instance of AbstractLinkedProcessorSlot, can't be added into ProcessorSlotChain");                 continue;             }                       // 添加到 chain 尾部             chain.addLast((AbstractLinkedProcessorSlot<?>) slot);         }         return chain;     } }

2. 责任链的处理过程

我们可以通过断点的方式来查看在 sortedSlotList 集合中所有的 solt  顺序如下图所示:

Sentinel 流控的原理是什么

我们可以通过如下的顺序进行逐个的简单的分析一下

  • nodeSelectorSolt

  • CusterBuilderSolt

  • LogSlot

  • StatisicSlot

  • AuthoritySolt

  • SystemSolts

  • ParamFlowSolt

  • FlowSolt

  • DegradeSlot

对于 Sentinel 的 Slot  流控协作流程可以参考官方给出的文档, 如下图所示:

Sentinel 流控的原理是什么

FlowSolt 流控

通过  NodeSelectorSolt、CusterBuilderSolt、StatisicSlot 等一系列的请求数据处理,在  FlowSolt会进入流控规则,所有的 Solt 都会执行 entry 方法,  如下所示

// FlowSolt 的 entry 方法 @Override public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count,                   boolean prioritized, Object... args) throws Throwable {   // 检查流量   checkFlow(resourceWrapper, context, node, count, prioritized);   fireEntry(context, resourceWrapper, node, count, prioritized, args); }

在后续的流程中,会执进行判断具体的流控策略,默认是快速失败,会执行 DefaultController  方法。

// DefaultController @Override public boolean canPass(Node node, int acquireCount, boolean prioritized) {   // 当前资源的调用次数   int curCount = avgUsedTokens(node);   // 当前资源的调用次数 + 1 > 当前阈值   if (curCount + acquireCount > count) {     // 删减比分代码     // 不通过     return false;   }   // 通过   return true; } private int avgUsedTokens(Node node) {   if (node == null) {     return DEFAULT_AVG_USED_TOKENS;   }   return grade == RuleConstant.FLOW_GRADE_THREAD ? node.curThreadNum() : (int)(node.passQps()); }

如果上面返回不通过会回到,那么会抛出  FlowException

public void checkFlow(Function<String, Collection<FlowRule>> ruleProvider, ResourceWrapper resource,                       Context context, DefaultNode node, int count, boolean prioritized) throws BlockException {   if (ruleProvider == null || resource == null) {     return;   }   Collection<FlowRule> rules = ruleProvider.apply(resource.getName());   if (rules != null) {     for (FlowRule rule : rules) {       if (!canPassCheck(rule, context, node, count, prioritized)) {         // 流控规则不通过,会抛出 FlowException         throw new FlowException(rule.getLimitApp(), rule);       }     }   } }

然后会在  StatisticSlot 中增加统计信息, 最后会抛出给 SentinelResourceAspect  进行处理,完成流控功能。我们再来看看这个异常信息,如果是BlockException 异常,会进入 handleBlockException 方法处理,  如果是其他的业务异常首先会判断是否有配置 fallback 处理如果有,就调用 handleFallback 没有就继续往外抛,至此完成流控功能

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; }

DegradeSlot 降级

断路器的作用是当某些资源一直出现故障时,将触发断路器。断路器不会继续访问已经发生故障的资源,而是拦截请求并返回故障信号。

Sentinel 在  DegradeSlot 这个 Slot 中实现了熔断降级的功能,它有三个状态 OPEN 、HALF_OPEN、CLOSED  以ResponseTimeCircuitBreaker RT 响应时间维度来分析, 断路器工作的过程。下面是一个标准断路器的工作流程:

Sentinel 流控的原理是什么

在 Sentinel  实现的源码过程如下图所示:

Sentinel 流控的原理是什么

Sentinel 通过 WEB  拦截器

Sentinel 在默认情况下, 不使用 @ResourceSentinel  注解实现流控的时候, Sentinel  通过拦截器进行流控实现的。初始化类在 SentinelWebAutoConfiguration  它实现了 WebmvcConfigurer 接口,在  sentinelWebInterceptor 方法初始化 SentinelWebInterceptor 等 Bean。

@Bean @ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled",                        matchIfMissing = true) public SentinelWebInterceptor sentinelWebInterceptor(   SentinelWebMvcConfig sentinelWebMvcConfig) {   return new SentinelWebInterceptor(sentinelWebMvcConfig); }

我们在  SentinelWebInterceptor 的核心方法 preHandle  中处理,这里面我们又可以看到 SphU.entry  熟悉的过程调用流控的责任链。由于逻辑都类似,此处不再多说。代码如下:

public boolean preHandle(httpservletRequest request, HttpServletResponse response, Object handler)   throws Exception {   try {     String resourceName = getResourceName(request);     if (StringUtil.isEmpty(resourceName)) {       return true;     }     if (increaseReferece(request, this.baseWebMvcConfig.getRequestRefName(), 1) != 1) {       return true;     }     // Parse the request origin using reGIStered origin parser.     String origin = parseOrigin(request);     String contextName = getContextName(request);     ContextUtil.enter(contextName, origin);     Entry entry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_WEB, EntryType.IN);     request.setAttribute(baseWebMvcConfig.getRequestAttributeName(), entry);     return true;   } catch (BlockException e) {     try {       handleBlockException(request, response, e);     } finally {       ContextUtil.exit();     }     return false;   } }

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网VUE频道,感谢您对编程网的支持。

--结束END--

本文标题: Sentinel 流控的原理是什么

本文链接: https://www.lsjlt.com/news/65995.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Sentinel 流控的原理是什么
    Sentinel 流控的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。@ResoureSetinel 工作原理配置流...
    99+
    2022-10-19
  • Sentinel的工作流程是什么
    本篇内容主要讲解“Sentinel的工作流程是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Sentinel的工作流程是什么”吧!Sentinel统计QPS...
    99+
    2022-10-19
  • ajax的原理和流程是什么
    Ajax的全称是Asynchronous JavaScript and XML,即异步JavaScript和XML。它是一种在Web...
    99+
    2023-05-13
    ajax的原理 ajax
  • Java 8 Stream流的原理是什么
    Java 8 Stream流的原理是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。前言:Stream 使用一种类似用 SQL 语句从数据库查询数据的直观...
    99+
    2023-06-22
  • Java之IO流原理及流的分类是什么
    这篇文章主要讲解了“Java之IO流原理及流的分类是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java之IO流原理及流的分类是什么”吧!一、概述I/O是Input/Output的缩写...
    99+
    2023-07-02
  • java jbpm工作流的原理是什么
    jBPM(Java Business Process Management)是一个基于Java的开源工作流引擎,它用于执行和管理业务...
    99+
    2023-09-09
    java
  • Java工作流Activity的原理是什么
    Java工作流Activity的原理是基于活动(Activity)的概念。活动是业务中的具体操作或步骤,可以是一个服务、一个任务或者...
    99+
    2023-10-19
    Java
  • java activity工作流的原理是什么
    Java Activity工作流的原理是基于BPMN(Business Process Model and Notation)的标准...
    99+
    2023-10-10
    java
  • java中数据流的原理是什么
    java中数据流的原理是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向对象...
    99+
    2023-06-14
  • webpack的打包流程和原理是什么
    这篇文章主要介绍“webpack的打包流程和原理是什么”,在日常操作中,相信很多人在webpack的打包流程和原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”webp...
    99+
    2022-10-19
  • python风控中KS原理是什么
    这篇文章主要为大家展示了“python风控中KS原理是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“python风控中KS原理是什么”这篇文章吧。一、业务背景在金融风控领域,常常使用KS指标...
    99+
    2023-06-25
  • mysql中并发控制的原理是什么
    mysql中并发控制的原理是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1、mysql的逻辑框架mysql逻辑框架图如下:最上层是处...
    99+
    2022-10-18
  • 云服务器免流原理是什么
    云服务器免流原理是指使用公共云服务免除用户在使用某个应用时需要付费购买或租赁某个应用服务的开销或者成本。 免流通常被认为是一种通过公共云服务提供的免费网络连接访问私有网络的能力。用户无需购买或租赁网络连接服务,而是使用公共云服务提供商的免...
    99+
    2023-10-26
    原理 服务器
  • dnslog原理及工作流程是什么
    DNSlog是一种常用于渗透测试和恶意软件分析的技术,通过利用DNS协议的特性,实现收集和分析恶意软件的通信行为。DNSlog的工作...
    99+
    2023-09-25
    dnslog
  • ssh框架原理及流程是什么
    SSH(Struts2+Spring+Hibernate)框架的项目,该架构主要分为三个层次:(1)Struts2:负责web层(2)Spring:业务层的管理(3)Hibernate:负责数据持久化Struts2工作原理:初始化一个指向s...
    99+
    2018-08-18
    java教程 java ssh框架 原理 流程
  • mybatis工作原理及流程是什么
    MyBatis是一种持久层框架,它的工作原理及流程如下:1. 配置文件加载:MyBatis首先读取配置文件(通常是mybatis-c...
    99+
    2023-08-14
    mybatis
  • 主流Docker网络的实现原理是什么
    这篇文章主要介绍了主流Docker网络的实现原理是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、容器网络简介容器网络主要解决两大核心问题:一是容器的IP地址分配,二是...
    99+
    2023-06-04
  • SpringBoot服务监控机制的原理是什么
    这期内容当中小编将会给大家带来有关SpringBoot服务监控机制的原理是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。SpringBoot 监控SpringBoot 中的监控可以分为 HTTP 端点...
    99+
    2023-06-14
  • 使用DataAnt监控Apache APISIX的原理是什么
    这篇文章主要介绍“使用DataAnt监控Apache APISIX的原理是什么”,在日常操作中,相信很多人在使用DataAnt监控Apache APISIX的原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的...
    99+
    2023-07-02
  • MySQL事务工作流程原理是什么
    本篇内容介绍了“MySQL事务工作流程原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!事务的原子性...
    99+
    2022-10-19
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作