Sentinel策略与持久化

2024-01-01 06:17:08

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

目录

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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。