笔者学习了尼恩大佬博客以及B站一些视频后总结了本篇博客,很多内容是复制了原博客的内容,主要用于自己面试复习,非常感谢尼恩老师的分享,原博客链接如下:3W字吃透:微服务 sentinel 限流 底层原理和实操_sentinel学习圣经-优快云博客https://blog.youkuaiyun.com/crazymakercircle/article/details/130556777
一、基础概念
1.1、响应时间RT
通常是指该系统所有功能的平均时间或者所有功能的最大响应时间,响应时间的绝对值并不能直接反映软件的性能的高低,软件性能的高低实际上取决于用户对该响应时间的接受程度。
1.2、吞吐量(Throughput)
系统在单位时间内处理请求的数量
1.3、并发用户数
系统可以同时承载的正常使用系统功能的用户的数量
1.4、QPS每秒查询率(Query Per Second)
QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准
1.5、服务雪崩效应
在微服务架构系统中通常会有多个服务,在服务调用中如果出现基础服务故障,可能会导致级联故障,即一个服务不可用,可能导致所有调用它或间接调用它的服务都不可用,进而造成整个系统不可用的情况。
出现服务雪崩效应的原因如下:
①硬件故障:如服务器宕机、机房断电、光纤被挖断等。
②流量激增:如异常流量、重试加大流量等。
③缓存穿透:一般发生在应用重启,所有缓存失效时,以及短时间内大量缓存失效时,因大量的缓存不命中,使请求直击后端服务,造成服务提供者超负荷运行,引起服务不可用。
④程序bug:如程序逻辑导致死循环或者内存泄漏等。
如何解决服务器雪崩的方法有以下这些:
①超时机制:在上游服务调用下游服务的时候,设置一个最大响应时间,如果超过这个时间,下游未作出反应,就断开请求,释放掉线程。
②限流机制:限流就是限制系统的输入和输出流量已达到保护系统的目的。为了保证系统的稳固运行,一旦达到的需要限制的阈值,就需要限制流量并采取少量措施以完成限制流量的目的。
③熔断机制:在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。
④降级机制:降级是从系统功能优先级的角度考虑如何应对系统故障。 服务降级指的是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。降级其实就是为服务提供一个兜底方案,一旦服务无法正常调用,就使用兜底方案。
1.6、微服务保护组件
hystrix :老牌 SpringCloud 微服务保护的组件
sentinel :SpringCloud 阿里巴巴 的 微服务保护组件,
二、sentinel使用
2.1、定义资源
资源:可以是任何东西,一个服务,服务里的方法,甚至是一段代码。
定义资源的方式有很多中,我自己项目中使用注解@SentinelResource,该注解主要包含以下几个属性:
①value:资源名称,必填。
②blockHandler:对应处理 BlockException的函数名称,必须为public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。
③blockHandlerClass:blockHandler 函数默认需要和原方法在同一个类中,如果不在同一个类,就指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析
④entryType:entry 类型,可选项(默认为 EntryType.OUT)
⑤defaultFallback
⑥fallback /fallbackClass
2.2、定义规则
规则主要有流控规则、 熔断降级规则、系统规则、权限规则、热点参数规则等:
2.3、sentinel 熔断降级
熔断降级对调用链路中不稳定的资源进行熔断降级是保障高可用的重要措施之一。
由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)
2.4、sentinel 流控(限流)
流量控制(Flow Control),原理是监控应用流量的QPS或并发线程数等指标,当达到指定阈值时对流量进行控制,避免系统被瞬时的流量高峰冲垮,保障应用高可用性。
通过流控规则来指定允许该资源通过的请求次数,一条限流规则主要由下面几个因素组成
private static void initFlowRules(){
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("HelloWorld");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// Set limit QPS to 20.
rule.setCount(20);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
- resource:资源名,即限流规则的作用对象,默认请求路径
- count: 限流阈值
- grade: 限流阈值类型(QPS 或并发线程数)
- limitApp: 流控针对的调用来源,若为 default 则不区分调用来源
- strategy: 调用关系限流策略,主要有:
- 直接:当api大达到限流条件时,直接限流
- 关联:当关联的资源到达阈值,就限流自己
- 链路:只记录指定路上的流量,指定资源从入口资源进来的流量,如果达到阈值,就进行限流,api级别的限
- controlBehavior: 流量控制效果(直接拒绝/失败、Warm Up(预热模式)、匀速排队)
Warm Up(冷启动,预热)模式:当流量突然增大的时候,我们常常会希望系统从空闲状态到繁忙状态的切换的时间长一些。即如果系统在此之前长期处于空闲的状态,我们希望处理请求的数量是缓步的增多,经过预期的时间以后,到达系统处理请求个数的最大值。
匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。阈值必须设置为QPS。这种方式主要用于处理间隔性突发的流量,例如消息队列。
热点规则 (ParamFlowRule):热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制
2.5、sentinel 系统保护
系统保护的目标是在系统不被拖垮的情况下,提高系统的吞吐率
系统规则支持以下的模式:
①Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。
②CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
③平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
④并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
⑤入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
2.6、黑白名单规则
2.7、sentinel滑动窗口
固定窗口算法/计数器算法:每个窗口都有一个计数器用于统计本窗口的流量,如果count+新申请的请求书>设定的QPS,就拒绝请求,固定窗口对于流量突发情况无法应对
举例:两个窗口,每个窗口长度为1秒,设置最大QPS为100,0-0.5内有10次请求,0.5-1秒内有60次请求,1-1.5秒内有60次请求,1.5-2秒内有10次请求,根据规则,两个窗口内都小于100QPS,但是在0.5-1.5内是超过100的,却无法触发限流
Sentinel底层在做统计QPS做快速失败时用的就是滑动时间窗算法。
滑动窗口算法是为了解决计数器法精度太低的问题,它将时间周期/一段时间分为N个小周期(窗口),分别记录每个小周期内的流量,根据时间将窗口往前滑动并删除过期的小时间窗口。最终只需要统计滑动窗口范围内的所有小时间窗口总的流量,通过动态调整时间窗口的大小和滑动步长,可以更精确的控制通过速率
Sentinel中是通过环形数组实现的,
滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确,但也无法完全精准
2.8、令牌通算法
令牌桶的大小固定,令牌的产生速度固定,但是消耗令牌(即请求)速度不固定(可以应对一些某些时间请求过多的情况),每个请求都需要先去获取令牌,如果能拿到令牌就可以放行。
令牌的发送速率可以设置,算法能按照新的发送速率调大令牌的发放数量,使得出口突发流量能被处理。
2.9、漏桶算法
漏桶算法是将访问请求放入漏桶中,水漏的速度就是每秒系统能处理的请求数,当请求达到限流值也就是桶放不下了,则进行丢弃(触发限流策略)。无论有多少请求,请求的速率有多大,都按照固定的速率流出,对应到系统中就是按照固定的速率处理请求。超过漏桶容量的直接抛弃。漏桶不能有效应对突发流量,但是能起到平滑突发流量(整流)的作用。
2.10、集群限流
利用Token Server和Token Client来实现,Client向Server发送请求,Server根据配置的规则决定是否限流