springcloud Alibaba Sentinel学习笔记

前言

本文为尚硅谷周阳《springcloud第二季》视频学习笔记

一、sentinel是什么

分布式系统的流量防护卫兵

1、sentinel和hystrix对比

sentinelhystrix
单独一个组件可以独立出来 需要程序员手工搭建监控平台
直接界面化的细粒度统一配置 没有一套web界面给我们进行细粒度化的配置

二、sentinel的下载安装运行

1、下载

# github下载链接,按照视频使用1.7版本
https://github.com/alibaba/Sentinel/releases/download/1.7.0/sentinel-dashboard-1.7.0.jar

2、安装运行

# 1、默认端口8080,注意不要被占用,有Java环境
java -jar sentinel-dashboard-1.7.0.jar

# 2、访问localhost:8080,账号密码为sentinel
localhost:8080

三、sentinel初始化监控

1、新建springboot项目

添加如下Maven依赖

        <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--spring web环境-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--nacos开启注册发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--sentinel持久化到nacos-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、配置application.yml

server:
  port: 8401
spring:
  application:
    name: springcloudAlibaba-sentinel
  cloud:
    nacos:
      discovery:
        # nacos注册中心地址
        server-addr: localhost:8848
    sentinel:
      transport:
        # 默认端口8719,如果被占用+1直到扫描到不被占用的端口
        port: 8719
        # sentinel dashboard地址
        dashboard: localhost:8080

3、启动类开启服务注册发现

@EnableDiscoveryClient
@SpringBootApplication
public class SpringcloudAlibabaSentinelApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringcloudAlibabaSentinelApplication.class, args);
    }

}

4、编写controller接口

@RestController
public class FlowLimitController {

    @GetMapping("/testA")
    public String testA(){
        return "testA...";
    }

    @GetMapping("/testB")
    public String testB(){
        return "testB...";
    }
}

5、查看sentinel dashboard

启动项目请求接口,刷新sentinel dashboard,懒加载,不请求接口dashboard没有服务列表

sentinel dashboard

四、sentinel流控规则简介

1、实时监控

可以查看接口访问情况

2、簇点链路

可以查看接口及其链路

五、sentinel流控规则详解

1、QPS直接失败

在”簇点链路“菜单可以点击资源名后对应的流控按钮,进入流控编辑页面

簇点链路进入流控编辑

也可以直接点”流控规则“菜单新增流控规则

流控规则新增流控规则

点击上图”高级选项“默认选项如下,填写单机阈值为1,点击新增

新增流控规则

请求接口超过流控频率(QPS即每秒请求数)

超过流控QPS

2、线程数直接失败

当调用该api的线程数达到阈值的时候,进行限流

添加线程数限流规则

线程数限流规则

超过每秒一次请求接口并没有超出流控提示(单线程)

显然线程数流控与QPS有所区别

 QPS线程数
解读 关门打狗 御敌于国门之外
理解 拦截请求 接收请求,但是只能处理指定配置阈值。好比银行柜台,银行进来很多客人,但是只有一个柜台,就只能处理一个人的业务,其他的虽然进入银行,但是不处理

多线程下,如果有线程在被处理,已经到达阈值,其他线程请求会提示超出流控

3、关联流控

当关联的资源A达到阈值时,就限流B(我感冒你吃药)

如:当支付接口达到阈值,可以限流下订单接口

B超出限流,A不能被访问

使用postman模拟并发阈值访问

模拟testB接口请求超过流控

testA接口由可以正常访问变为限制访问

testA被限制访问

直到testB接口访问结束(不超出设定阈值)后,testA访问正常

4、预热

快速失败直接抛出异常

查看源码来源于com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController

预热公式:阈值除以冷加载因子(coldFactor(默认3))

经过预热时长才达到阈值

此场景用于避免接口瞬间大幅度提升请求,导致系统打垮

配置如下:

预热流控配置

解读:阈值为10÷3(冷加载因子)取整=3,即从QPS3~10需预热五秒钟

源码来自于:

com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController#WarmUpController(double, int)

冷加载因子源码

5、排队等待

匀速排第,让请求以均匀的速度(严格,漏桶算法)通过,阈值类型必须设成QPS,否则无效

思路:拒绝”忙得时候忙死,闲的时候闲死“

配置如下:

排队等待流控配置

解释:testA每秒一次请求,超过就排队,等待超时时间为20秒

源码:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController

使用postman发送每秒一次接口请求,后台日志结果

testA接口请求后台日志

六、熔断降级

熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高)

对这个资源进行限制,让它快速响应失败

避免影响到其他资源导致级联错误

当资源被降级后,在接下来的时间降级窗口之内,对该资源的调用都自动熔断

默认行为抛出DegradeException

sentinel的断路器没有半开状态

半开状态解释:hystrix会检查请求是否有异常,有就打开断路器,没有就关闭断路器

1、RT(平均响应时间)

解释:秒级,RT超出阈值且在时间窗口内通过的请求>=5,两个条件同时满足时触发降级

窗口期过后关闭断路器

RT最大4900(更大的需求通过-Dcsp.sentinel.statistic.max.rt=xx设置虚拟机参数生效)

配置:

配置降级规则RT

代码接口模拟一秒处理请求响应

待测试接口代码

jmeter模拟1秒钟10个线程请求

jmeter压测设置

显然接口testB处理不了一秒钟10个请求,只能一秒钟一个

开启jmeter,请求接口发现接口被熔断

接口被熔断保护

待关闭jmeter后,请求正常响应

2、异常比例

解释:秒级,QPS>=5且异常比例(秒级统计)超过阈值时,触发降级

时间窗口结束后,关闭降级

配置:

异常比例熔断规则配置

接口代码模拟超过异常比例:

模拟接口异常代码

jmeter模拟一秒钟10个请求

jmeter模拟请求

请求接口,已经熔断保护

接口熔断保护

停止jmeter,请求接口,抛出错误

抛出错误

3、异常数

解释:分钟统计,超过阈值时,触发降级

时间窗口结束后,关闭降级

配置:

配置异常数熔断降级规则

需要注意的是,统计时间为分钟级

如果时间窗口小于60s,结束窗口期,仍可能进入熔断降级

配置时间窗口时间要大于60s

代码:

接口模拟异常数

请求接口五次异常以后,熔断降级

熔断降级

带时间超过窗口期时间,请求异常

超过窗口期,请求异常

七、热点规则限流

解释:

很多时候我们希望根据某些热点数据访问频次高的数据进行限制

如:苹果新发布手机,超话等

热点参数限流会根据传入的热点参数,单独限制流控

只对该热点参数的某些值进行限制

热点限流源码:

com.alibaba.csp.sentinel.slots.block.BlockException

限流的总体思想:

        try {
            // 逻辑符合限流规则
        } catch (Exception e) {
            // 进入限流
        } finally {
            
        }

1、热点规则

热点限流配置:

热点限流配置

代码:

热点限流代码

第一个参数p1不为空,请求频率超过一秒1次,执行兜底方法

执行兜底方法

请求第二个参数p2,不受影响

仍然执行hotkey接口

如果代码没有配置兜底方法

注解中无兜底方法配置

超过限流规则,则正常打出错误日志

没有兜底,打印错误日志

需要注意的是,只要含有指定限流规则的参数就会执行兜底,后面可以继续加别的参数

不只含p1参数

2、参数例外项

解释:即VIP通道

配置:

参数例外项配置

代码不变,请求接口超过1秒一次,但传入的参数为例外项,没有超出阈值,则没有执行限流

参数例外项

参数例外项支持一下七种参数类型

参数例外项支持参数类型

值得注意的是@SentinelResource不会影响代码正常的异常,没有超出限流仍会有异常抛出

八、系统规则

解释:即系统自适应限流

从整体的维度对应用入口流量进行配置

”防疫一刀切“(粒度变小)

配置:

系统规则

各个阈值类型解释:

a,LOAD自适应(仅对Linux/unix-like机器生效):系统的load1作为启发指标,进行自适应系统保护。

当系统load1超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR阶段)

系统容量由系统的maxQpsminRt估算得出。设定参考值一般是CPU cores*2.5

b,CPU usage(1.5.0+版本):当系统CPU使用率超过阈值即触发系统保护(取值范围0.0~1.0),比较灵敏。

c,平均RT:当单台机器上所有路口流量的平均RT达到阈值即触发系统保护,单位是毫秒。

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

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

九、@SentinelResource配置

对标@HystrixCommand

1、 三种配置方案及区别

代码如下:

@SentinelResource和兜底代码

a,若点击此按照配置限流规则

按照/接口名设置流控规则

流控规则

此时超过限流访问接口不会执行兜底方法

超出限流执行结果

b,若按照@SentinelSource注解的value值配置

按照@SentinelSource注解value值配置

新增流控配置

超过流控后执行了兜底方法

c,如果没有兜底方法配置,且流控配置为@SentinelSource的value值

代码:

没有兜底方法配置

配置:

配置资源名为@SentinelResource的value

超出限流规则后:

超出流控

2、上述兜底方法面临的问题

a,系统默认的,没有体现我们自己的业务要求

b,依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观

c,每个业务方法都添加一个兜底的,那代码膨胀加剧

d,全局统一的处理方法没有体现

十、客户自定义限流处理逻辑

编写统一处理限流异常类,注意方法有static和入参BlockException

代码:

统一处理限流异常类

此时业务接口@SentinelResource注解的值,可以按照需要配置

blockHandlerClass的值为限流异常处理

blockHandler为异常处理的具体方法

代码:

@SentinelResource属性值

配置:

流控配置

请求超出配置后执行结果:

执行结果

以上解决了兜底方法面临的问题,解耦处理、

注意:注解埋点不支持private方法

十一、 编写代码方式配置限流

不推荐,略

十二、sentinel在openFeign下熔断配置

1、搭建一个简单的openFeign远程调用环境

a,springcloudAlibaba-order(服务提供者)

引入pom依赖:

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

启动类:

@EnableDiscoveryClient // 开启服务注册发现
@SpringBootApplication
public class SpringcloudAlibabaOrderApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringcloudAlibabaOrderApplication.class, args);
  }
}

yml:

server:
  port: 8402
spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  application:
    name: springcloudAlibaba-order

代码:

@RestController
public class OrderController {

  private static HashMap<Long, String> dao = new HashMap<>();

  static {
    dao.put(1L, "orderDetail...1");
    dao.put(2L, "orderDetail...2");
    dao.put(3L, "orderDetail...3");
  }

  @GetMapping("/orderDetail/{id}")
  public String orderDetail(@PathVariable("id") Long id) {

    return dao.get(id);
  }
}

b,springcloudAlibaba-sentinel(服务消费者)添加配置

pom新增依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>

启动类新增注解:

@EnableFeignClients // 新增开启feign远程调用
@EnableDiscoveryClient
@SpringBootApplication
public class SpringcloudAlibabaSentinelApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringcloudAlibabaSentinelApplication.class, args);
    }

}

yml新增配置:

# 激活sentinel对feign的支持
feign:
  sentinel:
    enabled: true

代码:

新建远程调用feign接口

@FeignClient(value = "springcloudAlibaba-order", 
fallback = OrderFeignServiceFallbackService.class) // 降级实现类
public interface OrderFeignService {

    @GetMapping("/orderDetail/{id}")
    String orderDetail(@PathVariable("id") Long id);
}

降级实现类

@Component // 注意添加注解
public class OrderFeignServiceFallbackService implements OrderFeignService {

    @Override
    public String orderDetail(Long id){

        return "服务降级返回OrderFeignServiceFallbackService...";
    }
}

c,启动两个服务,在nacos可视化工具中查看服务是否注册成功

两个服务注册nacos成功

d,测试远程调用

远程调用成功

2、测试sentinel服务熔断降级

a,模拟服务崩溃,停用服务提供者(springcloudAlibaba-order)

springcloudAlibaba-order服务已被停掉

b,再次发起远程调用,执行服务熔断降级逻辑

服务降级处理

起到了防止服务调用不成功,一直重试卡死的情况

如果需要配置限流和兜底请自行添加@SentinelResource进行测试

需要注意的是fallback为Java异常处理,blockHandler为限流异常处理

十三、sentinel持久化规则

sentinel默认没有持久化配置信息,服务启动配置即消失

sentinel持久化采用结合nacos持久化的方案

将限流配置规则持久化存储到nacos保存

只要nacos配置不删除,则sentinel限流规则持续有效

a,nacos新建sentinel流控配置文件

nacos的sentinel流控配置

其中:

resource:资源名称;

limitApp:来源应用;

grade:阈值类型,0表示线程数,1表示QPS;

count:单机阈值;

strategy:流控模式,0表示直接,1表示关联,2表示链路;

controlBehavior:流控效果,0表示快速失败,1表示warmup,2表示排队等待;

clusterMode:是否集群;

b,增加sentinel持久化nacos的yml配置

spring:
  application:
    name: springcloudAlibaba-sentinel
  cloud:
    sentinel:
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: springcloudAlibaba-sentinel
            goupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

c,一定要请求一次(sentinel懒加载)对应流控的接口,方可发现sentinel Dashboard中有配置信息

sentinel Dashboard已经有流控配置信息

d,停掉服务,再次请求配置流控的接口,发现配置信息还在

posted @ 2024-10-21 16:22  大列巴同学  阅读(9)  评论(0编辑  收藏  举报  来源