阿里sentinel源码解析

阿里sentinel源码解析,第1张

sentinel是阿里巴巴开源的流量整形(限流、熔断)框架,目前在github拥有15k+的star,sentinel以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

我们以sentinel的主流程入手,分析sentinel是怎么搜集流量指标,完成流量整形的。

首先我们先看一个sentinel的简单使用demo,只需要调用SphU.entry获取到entry,然后在完成业务方法之后调用entry.exit即可。

SphU.entry会调用Env.sph.entry,将name和流量流向封装成StringResourceWrapper,然后继续调用entry处理。

进入CtSph的entry方法,最终来到entryWithPriority,调用InternalContextUtil.internalEnter初始化ThreadLocal的Context,然后调用lookProcessChain初始化责任链,最终调用chain.entry进入责任链进行处理。

InternalContextUtil.internalEnter会调用trueEnter方法,主要是生成DefaultNode到contextNameNodeMap,然后生成Context设置到contextHolder的过程。

lookProcessChain已经做过优化,支持spi加载自定义的责任链bulider,如果没有定义则使用默认的DefaultSlotChainBuilder进行加载。默认加载的slot和顺序可见镇楼图,不再细说。

最后来到重头戏chain.entry进入责任链进行处理,下面会按照顺序分别对每个处理器进行分析。

首先来到NodeSelectorSlot,主要是获取到name对应的DefaultNode并缓存起来,设置为context的当前节点,然后通知下一个节点。

下一个节点是ClusterBuilderSlot,继续对DefaultNode设置ClusterNode与OriginNode,然后通知下一节点。

下一个节点是LogSlot,只是单纯的打印日志,不再细说。

下一个节点是StatisticSlot,是一个后置节点,先通知下一个节点处理完后,

1.如果没有报错,则对node、clusterNode、originNode、ENTRY_NODE的线程数、通过请求数进行增加。

2.如果报错是PriorityWaitException,则只对线程数进行增加。

3.如果报错是BlockException,设置报错到node,然后对阻挡请求数进行增加。

4.如果是其他报错,设置报错到node即可。

下一个节点是FlowSlot,这个节点就是重要的限流处理节点,进入此节点是调用checker.checkFlow进行限流处理。

来到FlowRuleChecker的checkFlow方法,调用ruleProvider.apply获取到资源对应的FlowRule列表,然后遍历FlowRule调用canPassCheck校验限流规则。

canPassCheck会根据rule的限流模式,选择集群限流或者本地限流,这里分别作出分析。

passLocalCheck是本地限流的入口,首先会调用selectNodeByRequesterAndStrategy选出限流的node,然后调用canPass进行校验。

selectNodeByRequesterAndStrategy会根据以下规则选中node。

1.strategy是STRATEGY_DIRECT。

1.1.limitApp不是other和default,并且等于orgin时,选择originNode。

1.2.limitApp是other,选择originNode。

1.3.limitApp是default,选择clusterNode。

2.strategy是STRATEGY_RELATE,选择clusterNode。

3.strategy是STRATEGY_CHAIN,选择node。

选择好对应的node后就是调用canPass校验限流规则,目前sentinel有三种本地限流规则:普通限流、匀速限流、冷启动限流。

普通限流的实现是DefaultController,就是统计当前的线程数或者qps加上需要通过的数量有没有大于限定值,小于等于则直接通过,否则阻挡。

匀速限流的实现是RateLimiterController,使用了AtomicLong保证了latestPassedTime的原子增长,因此停顿的时间是根据latestPassedTime-currentTime计算出来,得到一个匀速的睡眠时间。

冷启动限流的实现是WarmUpController,是sentinel中最难懂的限流方式,其实不太需要关注这些复杂公式的计算,也可以得出冷启动的限流思路:

1.当qps已经达到温热状态时,按照正常的添加令牌消耗令牌即可。

2.当qps处于过冷状态时,会添加令牌使得算法继续降温。

3.当qps逐渐回升,大于过冷的边界qps值时,不再添加令牌,慢慢消耗令牌使得逐渐增大单位时间可通过的请求数,让算法继续回温。

总结出一点,可通过的请求数跟令牌桶剩余令牌数量成反比,以达到冷启动的作用。

接下来是集群限流,passClusterCheck是集群限流的入口,会根据flowId调用clusterSerivce获取指定数量的token,然后根据其结果判断是否通过、睡眠、降级到本地限流、阻挡。

接下来看一下ClusterService的处理,会根据ruleId获取到对应的FlowRule,然后调用ClusterFlowChecker.acquireClusterToken获取结果返回。ClusterFlowChecker.acquireClusterToken的处理方式跟普通限流是一样的,只是会将集群的请求都集中在一个service中处理,来达到集群限流的效果,不再细说。

FlowSlot的下一个节点是DegradeSlot,是熔断处理器,进入时会调用performChecking,进而获取到CircuitBreaker列表,然后调用其tryPass校验是否熔断。

来到AbstractCircuitBreaker的tryPass方法,主要是判断熔断器状态,如果是close直接放行,如果是open则会校验是否到达开启halfopen的时间,如果成功将状态cas成halfopen则继续放行,其他情况都是阻拦。

那怎么将熔断器的状态从close变成open呢?怎么将halfopen变成close或者open呢?sentinel由两种熔断器:错误数熔断器ExceptionCircuitBreaker、响应时间熔断器ResponseTimeCircuitBreaker,都分析一遍。

当业务方法报错时会调用Tracer.traceEntry将报错设置到entry上。

当调用entry.exit时,会随着责任链来到DegradeSlot的exit方法,会遍历熔断器列表调用其onRequestComplete方法。

ExceptionCircuitBreaker的onRequestComplete会记录错误数和总请求数,然后调用handleStateChangeWhenThresholdExceeded继续处理。

1.当前状态是open时,不应该由熔断器底层去转换状态,直接退出。

2.当前状态是halfopen时,如果没有报错,则将halfopen变成close,否则将halfopen变成open。

3.当前状态时close时,则根据是否总请求达到了最低请求数,如果达到了话再比较错误数/错误比例是否大于限定值,如果大于则直接转换成open。

ExceptionCircuitBreaker的onRequestComplete会记录慢响应数和总请求数,然后调用handleStateChangeWhenThresholdExceeded继续处理。

1.当前状态是open时,不应该由熔断器底层去转换状态,直接退出。

2.当前状态是halfopen时,如果当前响应时间小于限定值,则将halfopen变成close,否则将halfopen变成open。

3.当前状态时close时,则根据是否总请求达到了最低请求数,如果达到了话再比较慢请求数/慢请求比例是否大于限定值,如果大于则直接转换成open。

下一个节点是AuthoritySlot,权限控制器,这个控制器就是看当前origin是否被允许进入请求,不允许则报错,不再细说。

终于来到最后一个节点SystemSlot了,此节点是自适应处理器,主要是根据系统自身负载(qps、最大线程数、最高响应时间、cpu使用率、系统bbr)来判断请求是否能够通过,保证系统处于一个能稳定处理请求的安全状态。

尤其值得一提的是bbr算法,作者参考了tcp bbr的设计,通过最大的qps和最小的响应时间动态计算出可进入的线程数,而不是一个粗暴的固定可进入的线程数,为什么能通过这两个值就能计算出可进入的线程数?可以网上搜索一下tcp bbr算法的解析,十分巧妙,不再细说。

打算建立个人网站的话,准备以下的资料1.注册域名。最好能和企业主体有点关联2.选择网站系统。例如wordpress,zblog,emblog等都可以。3.选择云服务器,例如阿里或者腾讯等4.解析域名到服务器5.发布网站到云主机以上步骤还是需要一些知识的。步骤方法一、先去域名注册商那里注册一个自己喜欢的域名,常用的域名注册商有:万网、新网、西部数码等;二、需要选购租用一台服务器,考虑到是个人博客可以先选择使用虚拟主机;如果使用国内服务器或者虚拟主机的话,需要对域名进行备案,备案流程比较简单,可以联系服务器商代备即可。三、网站程序,这里是一个网站的核心。个人博客网站建议选用网站博客程序,常用的有WordPress、zblog等。四、对自己选好的网站程序本地搭建成网站,然后进行修改调整,使其成为自己专属的博客网站,本地搭建可以网上搜一下本地环境安装包来配置本地环境;再按照所用程序官方教程进行安装使用。五、网站调整好以后,需要通过FTP等工具把网站程序上传到服务器;然后在服务器绑定自己注册的域名;再去域名服务商那里对域名解析,解析到自己服务器上。六、等待域名解析生效后,在浏览器地址栏输入域名就可以访问自己的博客了,至此,网站建设完成。老魏为此写过云服务器手动建站等多篇教程,看完有疑问可以问,在线了就回答。

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案主要核心部件Remoting:网络通信框架,实现了sync-over-async和request-response消息机制.RPC:一个远程过程调用的抽象,支持负载均衡、容灾和集群功能Registry:服务目录框架用于服务的注册和服务事件发布和订阅。Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/592094.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-07-08
下一篇2023-07-08

发表评论

登录后才能评论

评论列表(0条)

    保存