Sentinel策略与持久化

发布时间:2024年01月01日

日升时奋斗,日落时自省?

目录

1、Sentinel主要功能

2、Sentinel基本概念

2.1、控制流量

2.1.1、常见流量控制算法

计数器算法

漏桶算法

?令牌桶算法

漏桶和令牌桶的区别

2.1.2、Sentinel流量控制

Sentinel 限流配置

流控模式

流控效果

2.2、熔断

Sentinel熔断配置(控制台)

熔断效果

2.3、热点

注意事项

2.4、授权规则

2.5、系统规则

2.6、自定义异常

3、使用Nacos存储数据

3.1、添加依赖

3.2、配置数据源

3.3、Nacos新建配置

4、Sentinel配置多个数据源

4.1、配置多数据源

4.2、Nacos新建熔断配置

5、sentinel执行流程


1、Sentinel主要功能

①流量控制: 可以通过配置规则对接口的访问量进行限制,避免因流量过高而导致系统崩溃。

②服务熔断: 当后端服务不可用或异常时,可以通过配置熔断规则,快速失败并返回错误信息,避免连锁故障。

③系统负载保护: 根据系统的负载情况,自动控制流量的通过,防止系统出现过载现象。

④统计和监控:提供实时的流量控制和熔断统计信息,可以通过Dashboard (控制台)进行可视化监控和配置。

注:以下展示的都是控制台的操作,当然代码也是可以进行设置的(并不常用,控制台会更灵活)

2、Sentinel基本概念

2.1、控制流量

流量控制是指对系统中的请求流量进行限制和管理,以确保系统在承受能力范围内正常运行。

2.1.1、常见流量控制算法

常见的流量控制实现算法有: 计数器限流、漏桶限流算法和令牌桶限流算法等。

计数器算法

计数器算法是在一定的时间间隔里,记录请求次数,当请求次数超过该时间限制时,就把计数器清零,然后重新计算。当请求次数超过间隔内的最大次数时,拒绝访问。

计数器算法的特点是: 实现比较简单,但存在“突刺现象”

突刺现象举例:请求限制为1秒内100次,如果0.2秒的时候100次就已经访问结束了,那后面还有的0.8秒就会等待被拒绝

漏桶算法

漏桶算法的实现思路是,有一个固定容量的漏桶,水流(请求)可以按照任意速率先进入到漏桶里,但漏桶总是以固定的速率匀速流出,当流入量过大的时候 (超过桶的容量),则多余水流 (请求) 直接溢出。

漏桶算法提供了一种机制,通过它可以让突发流量被整形,以便为系统提供稳定的请求,比如 Sentinel 中流量整形 (匀速排队功能)就是此算法实现的

?令牌桶算法

此篇博客?RequestRateLimiter部分简要概述说明

漏桶和令牌桶的区别

漏桶:允许请求的数量(水滴)流入是任意,请求数量流出是固定

令牌桶:允许请求的数量(令牌数量)流入是固定,请求数量流出是任意(在桶现有令牌数的范围内)

2.1.2、Sentinel流量控制

Sentinel 流量控制有以下几个角度

①资源的调用关系,例如资源的调用链路,资源和资源之间的关系

②运行指标,例如 QPS (Queries Per Second,每秒查询数) 、线程池、系统负载等。

③控制的效果,例如直接限流、冷启动、排队等。

Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果。

Sentinel 限流配置

注:这里使用的是控制台进行限流设置(是临时的,需要进行一次访问之后才能进行查看)

流控模式

直接:就是单一的限流我自己,也就是本路径

关联:就是我在某种情况下满足了阈值,跟我关联路径进行限流(关联资源)

链路:微服务有很多的链路构成,如果我们作为中间的一条链路,我们满足限流条件时,某条链路从入口处进行限流(对应入口资源)

流控效果

快速失败: 该方式是默认的流量控制方式,比如 QPS 超过任意规则的闻值后,新的请求就会被立即拒绝,拒绝方式为抛出 FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。

排队等待(也叫匀速通过):排队等待会严格控制请求通过的间隔时间,让请求稳定目匀速的通过,可以用来处理间隔性突发的高流量。例如抢票软件,在某一秒或者一分钟内有大量的请求到来,而接下来的一段时间里处于空闲状态,我们希望系统能够在接下来的空余时间里也能出去这些请求,而不是直接拒绝。在设置排队等待时,需要填写超时时间。

Warm Up: 此项叫做预热或者冷启动方式,此模式主要是防止流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮,通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到闻值上限,给冷系统一个预热的时间,避免冷系统被压垮。当使用 Warm Up 模式时,我们还需要指定启动时开放的 QPS 比例(DEFAULT_COLD_FACTOR,默认值为 3,代表 30%),以及系统预热所需时长 (warmUpPeriodSec,默认值是 10秒)

2.2、熔断

熔断是一种在分布式系统中处理故障和异常的策略。当某个服务或者接口发生故障或异常时,熔断机制会迅速将请求拒绝或者返回错误信息,而不是让请求一直等待或者重试,以保护系统免受故障的扩散影响。

当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。

熔断机制的好处:能够快速失败并返回错误信息,避免资源的浪费和系统连锁故障。当服务恢复正常时,熔断器会逐渐放心请求,验证服务的可用性,确保系统逐渐恢复正常运行

Sentinel熔断配置(控制台)

熔断效果

慢调用比例: 在统计时长内的所有请求,如果请求时间超过 xx 秒则为慢请求,且慢请求的超过一定的比例,且请求数大于最小请求数,将触发熔断操作,也就是一段时间内 (熔断时长参数设置)的请求会快速失败。

异常比例: 在统计时长内的所有请求,如果异常的比例大于闽值,且请求数大于最小请求数,将触发熔断,也就是一段时间内 (熔断时长参数设置)的请求会快速失败。

异常数:在统计时长内的所有请求,如果异常数大于闽值,且请求数大于最小请求数,将触发熔断,也就是一段时间内 (熔断时长参数设置)的请求会快速失败

2.3、热点

对某个接口的参数做流量限制,配置如下:

不难看出,大部分规则已经稳定

参数索引:就是访问时url后面的一些参数,从0下标开始计算

单机阈值:设置次数,热点访问请求次数,每台机器上

统计窗口时长: 多长时间内满足条件

注:这还不是热点限流的真正设置,设置完成之后来到热点规则会有一个编辑热点规则,这算是高级的热点规则:

点开高级选项之后 (点击向下的箭头可以提示很多类型)

这里以url?uid={id}?举例

参数值:指的就是例子中的id

限流阈值:在统一时间内访问多少次,进行热点限流

总述一下 当设置参数值为1,限流阈值为10时,表示当id=1时,在统一时间内请求访问10次过后,第11次就会进行热点限流

热点规则使用搭配注解@SentinelResource:

(1)热点规则只在控制配置是不生效的,需要在代码中配合@SentinelResource一起使用才行

(2)热点规则配置的参数必须存在,如果不存在配置也是无效的

    @SentinelResource(value = "getname",blockHandler = "myBlockHandler")
    @RequestMapping("/getname")
    public String getName(@RequestParam("uid") Integer uid) throws InterruptedException {
        Thread.sleep(100);
        return "Name :" + new Random().nextInt(100);
    }
    
    public String myBlockHandler(Integer uid ,BlockException blockException){
        if(blockException instanceof FlowException){
            return "注解-流量限流";
        }else if(blockException instanceof DegradeException){
            return "注解-熔断限流";
        }
        return "限流";
    }
注意事项

(1)SentinelResource注解有很多的参数,value是资源名,控制设置热点限流的资源名

(2)需要配置参数索引,所以方法必须由参数

(3)限流方法返回值和参数必必须和源方法一样,同时结尾还需要写BlockException 参数

2.4、授权规则

针对某个接口的调用服务做黑、白名单限制,设置如下:

流控设置是一个Header字段值

白名单:请求头中带有这个值的时候就可以放行

黑名单:请求头中不带这个值的时候就可以放行

授权实现关键有两步:

(1)在被调用服务中,获取授权字段

(2)在请求发起方,例如网关中添加授权字段

被调用服务中获取请求来源

@Component
public class CustomerRequestOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        //前端的请求参数 设置一个key-value  这里拿到
        String origin=httpServletRequest.getHeader("origin");
        if(StringUtils.isEmpty(origin)){   //这个位置看情况 分配主要区分的为 unstandard 是一个值,不是为空
            origin="blank";
        }
        return origin;
    }
}

?使用postman访问url后的效果,黑名单友友们自己去尝试一下

?2.5、系统规则

Load 自适应(仅对 Linux/Unix-like 机器生效): 系统的负载 load1 为启发指标,进行自适应系统保护load1 是每分钟平均负载指标,当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5.

RT: Response Time,系统响应时间,当单台机器上所有入口流量的平均 RT 达到闻值,即触发系统保护,单位是毫秒。

线程数: 当单台机器上所有入口流量的并发线程数达到闯值即触发系统保护

入口 QPS: 当单台机器上所有入口流量的 OPS 达到值即触发系统保护

CPU 使用率: 当系统 CPU 使用率超过值即触发系统保护 (取值范围 0.0-1.0)。?(windows上一般是不行的)

2.6、自定义异常

为了方便我们知道是什么情况产生的降级处理,我们可以继承BlockExceptionHandler接口自定义不同异常响应

@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
        int code= HttpStatus.TOO_MANY_REQUESTS.value();
        String msg="未知异常";
        if(e instanceof FlowException){
            msg="请求被限流了";
        }else if(e instanceof DegradeException){
            msg="请求被熔断了";
        }else if(e instanceof ParamFlowException){
            msg="请求触发了热点限流";
        }else if(e instanceof AuthorityException){
            code=HttpStatus.UNAUTHORIZED.value();
            msg="暂无权限";
        }
        httpServletResponse.setContentType("application/json;charset=utf-8");
        httpServletResponse.setStatus(code);
        httpServletResponse.getWriter().println("{\"code\":"+code+",\"msg\":"+msg+"}");
    }
}

3、使用Nacos存储数据

Sentinel 使用 Dashboard 可以动态修改流控规则,但因为默认是存在内存中的,所以重启之后数据就丢失了,因此我们可以配合 Nacos、ZooKeeperRedis、 etcd、Consul、Spring Cloud Config、Kubernetes CRD 等存储数据源。

按照以下步骤:

(1)添加依赖

(2)配置数据源

(3)Nacos新建限流/熔断规则

3.1、添加依赖

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

后面将配置可以配置到Nacos配置中心时,可以添加上nacos-config依赖

3.2、配置数据源

spring:
  application:
    name: sentinel-dashboard-demo
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
    sentinel:
      transport:
        dashboard: localhost:18086
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            username: nacos
            password: nacos
            data-id: ${spring.application.name}-flow-rules
            group-id: DEFAULT_GROUP
            data-type: json
            rule-type: flow

配置解析:

ds1:就是一个数据源名字,可以随便起名

nacos:表示nacos数据源

server-addr:Nacos服务器地址

username:Nacos用户名

password: Nacos 密码

data-id: Nacos 新建配置的 Data ID。

group-id: 分组 ID? ? ?这里使用${配置参数} 获取的就是服务名称,友友们可以写成固定的

data-type: 数据格式

rule-type: 规则类型,它有:

????????flow: 限流类型

????????degrade: 熔断限流类型

????????system:系统保护类型

3.3、Nacos新建配置

上面data-id对应配置中心的Data ID,group-id对应Group

配置内容:

?参数解释:

字段说明默认值
resource资源名,资源名是限流规则的作用对象
count限流阈值
grade限流阈值类型,QPS(1) 或线程数(0)模式QPS 模式
limitApp流控针对的调用来源default,代表不区分调用来源
strategy调用关系限流策略:直接(0)、链路(2)、关联(1)根据资源本身(直接)
controlBehavior流控效果:直接拒绝(0) / 排队等待 (2)/ 慢启动模式(1),不支持按调用关系限流直接拒绝

4、Sentinel配置多个数据源

Sentinel 配置多数据源,比如既配置 Nacos 的限流策略,还配置 Nacos 的熔断策略,它实现步骤和上一个小节类似,只有需要在项目中配置多个Nacos 数据源,并且在 Nacos 中新建一个熔断的配置,具体操作如下

4.1、配置多数据源

spring:
  application:
    name: sentinel-dashboard-demo
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
    sentinel:
      transport:
        dashboard: localhost:18086
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            username: nacos
            password: nacos
            data-id: ${spring.application.name}-flow-rules
            group-id: DEFAULT_GROUP
            data-type: json
            rule-type: flow
        ds2:
          nacos:
            server-addr: localhost:8848
            username: nacos
            password: nacos
            data-id: ${spring.application.name}-sentinel-degrade
            group-id: DEFAULT_GROUP
            data-type: json
            rule-type: degrade

4.2、Nacos新建熔断配置

配置信息去官网上都有提供

Field说明默认值
resource资源名,即规则的作用对象
grade熔断策略,支持慢调用比例(0)/异常比例(1)/异常数(2)策略慢调用比例
count慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
timeWindow熔断时长,单位为 s
minRequestAmount熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入)5
statIntervalMs统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入)1000 ms
slowRatioThreshold慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

注:这里的同步都是单向同步的,nacos设定规则会在启动时同步给sentinel控制台,但是控制台修改是不能返回给nacos的,需要特殊处理才能实现双向通信(针对个人版sentinel)

5、sentinel执行流程

其实图很很明显了,这里只是告诉友友们一个注意点

监控统计也是有顺序的,先检测热点规则,最后才是流量控制和熔断

文章来源:https://blog.csdn.net/c_study__c/article/details/135168455
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。