Sentinel-限流降级

本文介绍了Sentinel流量控制和服务保护技术,包括雪崩问题的解决策略、限流、熔断降级、授权规则以及规则持久化。重点讲解了如何在微服务环境中整合Sentinel,提供了一种预防和应对服务故障的全面解决方案。
摘要由CSDN通过智能技术生成

0.目录

初识Sentinel
流量控制
隔离和降级
授权规则
规则持久化

1.初识Sentinel

1.0目录

雪崩问题及解决方案
服务保护技术对比
Sentinel介绍和安装
微服务整合Sentinel

1.1 雪崩问题

1.1.1 引起雪崩的原本

如果服务D出现了问题,那么当服务A调用服务D时,会导致线程阻塞,资源得不到释放;随着时间的推移,越来越多访问服务D的线程都被阻塞,导致服务A的资源被耗尽。服务D出现问题,结果导致调用它的服务A也出现了问题。
image.png

微服务调用链路中,由于某个服务故障,进而引起整个链路中所有的服务都不可用,这就是雪崩。
image.png

1.1.2 雪崩问题的解决方式

(1)超时处理
客户端设置调用远程服务的超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止的等待。
它可以缓解雪崩问题,但是不能根本解决雪崩问题。如果请求qps量大于超时的释放量,最终也会导致雪崩。
(2)舱壁模式
限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,也叫线程隔离。
会有一定的资源浪费,比如业务2的10个线程由于服务C异常而导致不能处理任务业务而被浪费。
客户端进行处理
image.png
(3) 熔断降级
由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。
客户端统计然后处理。
image.png

(4)流量控制
限制业务访问的QPS,避免服务因流量的突增而故障。
服务端处理。预防性质
image.png

以上四种方式可以结合使用。

方式处理端缺点Sentinel是否支持
超时处理Client不能杜绝N
线程隔离Client资源浪费Y
熔断降级Client复杂,需要统计,而且需要设置恢复访问的规则Y
流量控制Server预防性质,防止服务因突发流量而故障Y

1.2 服务保护技术对比

image.png

1.3 Sentinel介绍和安装

Sentinel是CS架构,需要安装server端
下载地址:https://github.com/alibaba/Sentinel/releases/tag/1.8.1

启动:java -jar xxx.jar
访问:localhost:8080
用户名密码:sentinel/sentinel

image.png

1.4 微服务整合Sentinel

(1)引入依赖
:::info
com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel
:::
(2)配置Sentinel Server地址
:::info
spring.cloud.sentinel.transport.dashbord=localhost:9090
:::
(3)访问微服务的任务断点(controller),触发sentinel监控

2.流量控制

2.0 目录

快速入门
流控模式
流控效果
热点参数限流

2.1 快速入门

2.1.1.簇点链路

就是项目内的调用链路,链路中被监控的每个接口就是一个资源。默认情况下,sentinel会监控springMVC的每个端点(Controller),因此springmvc的每一个端点就是调用链路中的一个资源。

流控和熔断降级都是针对簇点链路中的资源来设置的,

(1)流控
image.png
image.png
QPS就是指限流的大小,单机阈值为1表示每秒只能处理一个请求,多出来的请求不再处理,返回429,flow limiting
针对来源,表示哪些访问该资源的请求进行限制,default表示不做区分,所有的请求都受这个规则控制。

从上面的描述可以看出,这个流控是在server端设置的,可以针对不同的client端进行单独设置。

2.1.2 高级选项

image.png

2.2 流控模式

2.2.1 直接

统计当前资源的请求,触发阈值时对当前资源直接限流,是默认模式。

2.2.2 关联

统计与当前资源相关的另一个资源,触发阈值时,对当前资源进行限流。
使用场景:比如用户支付时需要修改订单状态,同时用户需要查询订单。查询和修改订单会竞争,但明显修改订单的优先级要高于查询订单,因此,当修改订单业务触发阈值时,对查询订单进行限流。
image.png

2.2.3 链路

统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流
只针对从/test2链路进来的请求进行流量控制

image.png

(1)定义资源
:::info
@SentinelResource
:::
(2)sentinel默认会将controller方法做context整合,导致链路模式的流控失效,需要修改配置
:::info
spring.cloud.sentinel.web-context-unify=falses
:::

2.3 流控效果

包括三种流控效果:
(1)快速失败:达到阈值后,新的请求立即拒绝并抛出FlowException异常,这是默认的处理方式
(2)warm-up:预热模式,对超出阈值的请求同样是拒绝并抛出异常,但这种模式的阈值在刚启动阶段会缓慢增加,知道设置的最大值;
(3)排队等待:让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长,超过最大等待时间的请求被直接拒绝。
1683892859237.png

2.3.1 warm-up

设置两个值:threshold,coldFactor和 阈值时长,请求阈值初始值是threshold/coldFactor
1683893688105.png

2.3.2 排队等待

当请求超过qps阈值时,先让请求进入一个队列,然后按照阈值允许的时间间隔一次执行。后来的请求必须等待前面的执行完成,如果请求预期的等待时间超过最大时长,则会被拒绝。
流量整形

1683893779935.png

2.4 热点参数限流

之前的限流是统计访问某个资源的所有请求,判断是否超过QPS阈值。而热点参数限流是分别统计参数值相同的请求,判断是否超过QPS阈值。
1683894017568.png

默认参数设置:
1683894062299.png
代表对该资源host的 0号参数进行统计,每一秒相同参数值的请求不超过5.

高级配置:
image.png
设置2个例外:
(1)如果参数为100,那么qps为10
(2)如果参数为101,那么qps为15

注意:
热点参数限流对默认的springmvc资源无效,需要使用sentinelResource注解参能生效。

3.隔离和降级

3.0 目录

FeignClient整合Sentinel
线程隔离(舱壁模式)
熔断降级

3.1 FeignClient整合Sentinel

当服务出现故障时,容易传染给调用它的服务。隔离和降级是对客户端(调用方)的保护,相关的代码写在服务的调用方。
(1)修改配置文件,开启Feign的Sentinel功能
:::info
feign.sentinel.enabled=true
:::
(2)给FeignClient编写失败后的降级逻辑
1)FallbackClass,无法对远程调用的异常做处理
2)FallbackFactory,可以对远程调用的异常做处理,优选方案

3.2 线程隔离

image.png
实现方法:
线程池隔离,信号量隔离(sentinel只支持这种方式)
image.png

线程池隔离中,会给每一个远程调用创建独立的线程,可以独立控制这个远程调用,如果超时,则终止这个线程,实现主动超时。
对于信号量隔离,调用远程服务时,使用的是原来的线程,也就无法实现主动超时,也不能异步调用。

配置限流规则时,阈值类型选择线程数就是在使用信号量隔离模式。(名字取的太恶心了)
image.png

为什么服务端的限流不能用线程数呢?
这里的线程数是指客户端在请求服务端时,最多同时能有5个请求在执行,当一个请求返回时,信号量回收一个,下一个请求可以利用该回收的信号量去请求服务端。
但服务端的限流是qps,也就是每秒钟能接收多少请求进来,即使这些请求需要处理很长时间,但至少进入下一秒,上一秒的请求即使全部都还没有处理完毕,也能接着接收请求。

3.3 熔断降级

由断路器统计服务调用的异常比例和慢请求比例,如果超出阈值则会熔断该服务,即拦截访问该服务的一切请求;而当服务恢复时,断路器会放行访问该服务的请求。
该功能是由Sentinel内部的状态机实现的。
image.png
断路器熔断策略有三种:慢调用,异常比例,异常数

3.3.1 熔断策略-慢调用

业务的响应时长RT大于指定时长的请求认定为慢调用请求。在指定时间内,如果请求数量超过设定的最小数量,慢调用比例大于设定阈值,则触发熔断。
image.png

解读:RT超过500ms的调用时慢调用,统计最近10000ms内的请求,如果请求量超过10次,并且慢调用比例不低于0.5,则触发熔断,熔断时长为5s,然后进入half-open状态,放行一次请求做测试。

3.3.2 熔断策略-异常比例,异常数

统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常的比例达到设定的比例阈值(或超过指定异常数),则触发熔断。
image.png
统计最近1000ms内的请求,如果请求量超过10次,并且异常比例不低于0.4,则触发熔断,熔断时长为5秒。然后进入half-open状态,放行一次请求做测试。
image.png

image.png

4.授权规则

image.png

4.0 目录

授权规则
自定义异常结果

4.1 授权规则

对网关漏洞的补救。

授权规则可以对调用方的来源做控制,有白名单和黑名单两种方式。
白名单:来源(origin)在白名单内的调用者允许访问
黑名单:来源(origin)在黑名单内的调用者允许访问

image.png
流控应用填的是来源(origin)

例如,我们限定只允许从网关过来的请求访问orderservice,那么流控应用中就填写网关的名称
image.png

Sentinel是通过RequestOriginParser这个接口的parseOrigin来获取请求来源。
image.png

4.2 自定义异常结果

默认情况下,发生限流、降级、授权拦截时,都会抛出异常到调用方,而且异常默认都是限流异常,flow limiting,这样不太太友好。如果想要自定义异常时的返回结果,需要实现BlockExceptionHandler接口:
image.png
BlockException包含很多子类:
image.png

5.规则持久化

5.0 目录

规则管理模式
实现push模式

5.1 规则管理模式

规则管理有3中模式:
原始模式:默认,将规则保存在内存中,重启服务会丢失
pull模式:控制台将配置规则推送到客户端,而客户端会将配置规则保存在本地文件或者数据库中,以后会定时去本地文件或数据库中查询,更新本地规则。
image.png
push模式:推荐模式。控制台将配置规则推送到远程配置中心,例如nacos。客户端监听nacos,获取配置变更的推送消息,完成本地配置更新。
image.png

5.2 实现push模式

Sentinel的配置默认是推送到客户端的,如果需要推送到nacos,那么需要修改源码。

6.源码分析

6.1 Sentinel和Hystrix的线程隔离的区别

image.png

image.png

6.2 Sentinel的限流与Gateway的限流区别

限流的常见算法:计数器(窗口计数器,滑动窗口计数器),令牌桶(Token bucket),漏桶(Leaky bucket)

6.2.1 固定窗口计数器算法

(1)将时间划分成多个窗口, 窗口时间跨度成为Interval,比如1000ms;
(2)每个窗口维护一个计数器,每有一次请求就将计数器加1,限流就是设置计数器阈值,比如设置为3;
(3)如果计数器超过了限流阈值,则超出阈值的请求都被丢弃。
缺点:
两个窗口的连续时间段内有大量请求,但是又没有超过阈值,导致限流失效,但是服务器可能因为负载过大而宕机。
image.png

6.2.2 滑动窗口计数器算法

滑动窗口计数器会将一个窗口划分为n个更小的区间,例如
(1)窗口时间跨度Interval为1秒,区间数量n=2,则每个小区间的时间跨度为500ms;
(2)限流阈值依然为3,时间窗口内请求超过阈值时,超出的请求被限流;
(3)窗口会根据当前请求所在时间(currentTime)移动,窗口范围从(currentTime - Interval)之后的第一个时区开始,到currentTime所在时区结束。

重要概念:窗口,区间

缺点:不能完全解决固定窗口计数器的问题,但可以通过增加区间数量来降低该问题出现的概率。
而且,滑动窗口的实现复杂。
image.png

6.2.3 令牌桶

以固定速率生成令牌,存入令牌桶中,如果令牌桶满了以后,多余的令牌会丢弃。
请求进来以后,必须先尝试从桶中获取令牌,获取到令牌后才可以被处理。
如果令牌桶中没有令牌,则请求等待被丢弃。

缺点:令牌只有满了之后才会被丢弃,存放在令牌桶中的令牌可能会在下一秒内被消费,而且下一秒自己产生的令牌也可能被消费,导致下一秒的qps可能达到令牌桶存放令牌的数量 + 一秒内生成的令牌数量。
image.png

6.2.4 漏桶算法

将每个请求视作水滴放入漏桶;
漏桶以固定速率向外漏出请求来执行,如果漏桶空了,则停止漏水;
如果漏桶满了,则多余的水滴会被丢弃。

image.png

Sentinel在实现漏桶时,采用了队列等待模式;
让所有请求进入一个队列中,然后按照阈值允许的时间间隔一次执行,并发的多个请求必须等待,预期的等待时长 = 最近一次请求的预期等待时间 + 允许的间隔,如果请求预期的等待时间超出最大时长,则会被拒绝。
例如:QPS = 5,意味着没200ms处理一个队列中的请求,timeout=2000,意味着预期等待超过2000ms的请求会被拒绝。

image.png

image.png

6.3 源码基本概念

Sentinel本质要做的事情就是:
(1)统计数据:统计某个资源的访问数据,如QPS, RT等信息
(2)规则判断:判断限流规则,隔离规则,降级规则,熔断规则是否满足

6.3.1 ProcessorSlotChain

责任链,将不同功能,如限流,降级封装成一个个的slot,请求进入后逐个执行。
image.png
(1)前面三个slot是用来做数据统计的,后面的插槽是用来做规则判断的
(2)NodeSelectorSlot:用来构建调用链路,XXXNode
(3)ClusterBuilderSlot:用来构建全局数据统计的簇点
(4)StatisticsSot:真正做数据统计的节点,如滑动窗口

6.3.2 Node

节点可以理解为与资源相关的一个类。
节点包括两类:
DefaultNode:代表链路树中的每一个资源,一个资源出现在不同链路中时,会创建不同的节点,ExtranceNode是一种特殊的节点,入口节点。链路模式的限流规则中会使用到。
ClusterNode:代表资源,一个资源不管出现在多少链路中,只会有一个ClusterNode,记录的是当前资源被访问的所有统计数据之和。实现默认模式和关联模式的限流规则。

image.png
image.png

6.3.3 Entry

默认情况下,controller中的方法会被作为资源,其他要额外定义为资源的方法需要使用Entry来表征。Entry表示的就是一种需要被保护的资源。
(1)编码声明资源
image.png
(2)注解式声明资源
@SentinelResource

6.3.4 Context

默认情况下,controller不是EntranceNode,sentinel_spring_web_context是在Sentinel初始化context时创建的EntranceNode。
(1)什么是context?
context代表调用链路上下文,贯穿一次调用链路中的所有资源(Entry),基于ThreadLocal;
context维持着入口节点(EntranceNode),本次调用链路资源节点(curNode),调用来源(origin)等信息;
后续的Slot都可以通过context拿到DefaultNode胡总和ClusterNode,从而获取统计数据,完成规则判断;
context初始化的过程中,会创建EntranceNode,contextName就是EntranceNode的名称。
image.png

6.3.5 调用流程

1.调用入口:
AbstractSentinelInterceptor
(1)获取resourceName,也就是controller方法的RequestMapping
(2)获取contextName,默认是sentinel_spring_web_context
(3)获取origin,基于自定义的RequestOriginParser来获取
(4)初始化context,ContextUtils.enter(contextName, origin)
1)创建EntranceNode(contextName)
2)创建Context,放入ThreadLocal
(5)标记资源,创建Entry
Entry e = SphU.entry(resourceName)
然后,entry就会执行ProcessorSlotChain

image.png
每一个Entry都会有一个执行链,数据统计,创建节点,然后限流判断等操作。
每一个资源有一个自己的执行链,不同的资源有不同的执行链

6.4 ProcessorSlotChain执行流程

SphU.entry(resourceName)会根据当前的资源创建一个执行链(SPI加载)
一个请求链路一个context
一个资源,一个clusterNode
image.png
image.png

6.5 StatisticSlot

先放行,处理没有问题,那么再统计passNum和ThreadNum,还要给clusterNode也计数

6.6 AuthoritySlot

image.png

6.7 SystemSlot

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值