SpringCloud Alibaba Sentinel 详解

SpringCloud Alibaba Sentinel 详解

一、Sentinel 介绍

Sentinel 是面向云原生微服务的流量监控,熔断降级组件。能够监控并保护你的微服务。

Sentinel中文文档

Hystrix 和 Sentinel 对比:
在这里插入图片描述

Sentinel 的主要特征:
在这里插入图片描述

二、Sentinel 下载和安装

Sentinel 分为两个部分:

  1. 核心库(Java客户端)不依赖任何框架/库,能够运行于所有Java运行时环境,同时对Dubbo/Spring Cloud 等框架也有较好的支持。
  2. 控制台(Dashboard)基于Spring Boot 开发,打包后可以直接运行,不需要额外的Tomcat等应用容器。

使用docker 安装sentinel:

  1. 下载sentinel 镜像
docker pull bladex/sentinel-dashboard
  1. 创建sentinel 容器并运行
docker run --name sentinel -d -p 8858:8858 -d bladex/sentinel-dashboard
  1. 测试访问 :http://114.55.56.149:8858/#/login
    在这里插入图片描述

Windows 下安装 sentinel

  1. sentinel下载地址
    在这里插入图片描述

  2. 通过命令java -jar 运行jar包

  3. 访问localhost:8080

在这里插入图片描述

三、Sentinel 使用

1. Sentinel 初始化监控

  1. 创建项目 cloudalibaba.sentinel.service8401
  2. POM引入依赖
<dependencies>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- springcloud alibaba 后续做持久化用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>


        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency> <!--引入自己定义的api通用包,可以使用payment支持Entity-->
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
  1. yml 文件
server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        #Nacos服务注册中心地址
        server-addr: 114.55.56.149:8849
    sentinel:
      transport:
        # 配置sentinel dashboard地址
        dashboard: localhost:8080
        # 默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
        port: 8719
#        clientIp: localhost

management:
  endpoints:
    web:
      exposure:
        include: '*'

注: 由于这里的项目启动和sentinel启动都是本地,所以无需配置ClientIp。如果是虚拟机中安装的Sentinel,则ClientIp需要配置成项目启动地址(即 cloudalibaba.sentinel.service8401 启动地址)。如果Sentinel无法监控项目,则需要排查Sentinel启动地址能否访问项目启动地址了。

  1. 主启动类
package com.atguigu.springcloud.alibaba;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class MainApp8401 {

    public static void main(String[] args){

        SpringApplication.run(MainApp8401.class,args);
    }
}

  1. 控制层controller
package com.atguigu.springcloud.alibaba.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FlowLimitController {

    @GetMapping("/testA")
    public String testA(){

        return "-----testA";
    }

    @GetMapping("/testB")
    public String testB(){

        return "-----testB";
    }

}

测试:由于sentinel使用的懒加载机制,所以无法看到监控到的数据。当我们访问Controller中的方法后,发现可以监控到我们的服务方法了。
在这里插入图片描述

2. Sentinel 流控规则介绍

在这里插入图片描述

  • 资源名:唯一名称,默认请求路径
  • 针对来源:Sentinel 可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
  • 阈值类型/单机阈值:
    - QPS(每秒钟的请求数量):当调用该api的QPS达到阈值的时候,进行限流
    - 线程数:当调用该api的线程数达到阈值的时候,进行限流
  • 是否集群:不需要集群
  • 流控模式:
    - 直接:api达到限流条件时,直接限流
    - 关联:当关联的资源达到阈值时,就限流自己
    - 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)(api的级别的针对来源)
  • 流控效果:
    - 快速失败:直接失败,抛异常
    - Warm Up:根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值

3. Sentinel 流控模式

  1. QPS:我们可以对某个请求进行限流设置。比如上述的/testA请求,我们可以设置一秒钟内只能访问一次,超过一次则返回错误。通过Sentinel的流控设置即可完成。
    在这里插入图片描述
    在这里插入图片描述

测试:我们访问localhost:8041/testA,当我们每秒访问一次则可以正常访问,当超过一次则返回如下信息:
在这里插入图片描述

  1. 并发线程数:可以同时处理多个客户端发送过来的请求,超过了,则返回错误信息。

  2. 关联:当关联的资源达到阈值时,就限流自己。当与A关联的资源B达到阈值后,就限流A。
    在这里插入图片描述
    当管关联资源/testB的qps阈值超过1时,就限流/testA的Rest访问地址,当关联资源到达阈值后限制配置好的资源名
    比如我们实际开发中,订单下单后需要调用支付接口,当我们的支付接口到达极限要瘫了,就能 去限制订单下单的接口。

  3. 链路:只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值。这篇文章有对链路详细介绍和测试。链路文章地址

4. Sentinel 流控效果

  1. 快速失败:即上述测试的,请求到达阈值后,直接返回错误信息。
  2. Warm Up:默认coldFactor为3,即请求QPS从threshold/3开始,经预热时长逐渐升至设定的QPS阈值。
    使用场景:比如某个请求平时访问量低,但是某些时刻访问量特别大,可能直接是系统瘫痪,Warm Up 就起到作用了。
    还有就是常说的秒杀系统。在开启的瞬间,很多流量上来,很有可能吧系统打死,预热方式就是为了保护系统,可慢慢的吧流量放进来,慢慢的把阈值增长到设置的阈值。
    如何使用呢,以如下图片为例:
    在这里插入图片描述
    图片中阈值为10,但是我们要除以coldFactor = 3,表示一开始阈值其实只有3,然后给预热时长5秒,5秒内慢慢的从3 过渡到10。而不是一下就可以接受每秒10次请求。

测试: 我们将/testA设置为上图设置。然后疯狂请求/testA,发现开始的时候每秒请求超过3此后会返回默认的错误信息,五秒过后,就能正常的响应三次过后的请求了!

  1. 排队等待:
    在这里插入图片描述
    在这里插入图片描述

5. Sentinel 降级

Sentinel 降级又称熔断降级。
降级策略有三个:

  1. RT:平均响应时间,秒级。分均响应时间,超出阈值且在时间窗口内通过的请求 >=5,俩个条件同事满足后出发降级,窗口期过后关闭断路器。RT最大4900(更大的需要通过- Dcsp.sentinel.statistic.max.rt=XXXX才能生效)
  2. 异常比例:秒级。QPS >= 5 且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级。
  3. 异常数:分钟统计。超过阈值时,触发降级;时间窗口结束后,关闭降级。
    在这里插入图片描述
    Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其他的资源二导致级联错误。
    当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都会自动熔断(默认行为是抛出DegradeException)。
    Sentinel 的断路器是没有半开状态的

1. RT

在这里插入图片描述测试:在这里插入图片描述
表示我们的/testD请求,必须在200ms秒内处理完请求,且请求数要小于等于五的,否则发生熔断。熔断后,再下一秒后(窗口时间),服务才恢复。然而在这一秒钟(时间窗口)内,服务是不可用的(熔断了)。

2. 异常比例

当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值超过阈值之后,资源进入降级状态,即接下来的时间窗口之内,对这个方法的调用都会自动的返回。异常比率的阈值范围是 [0.0 , 1.0],代表0% - 100%。
在这里插入图片描述

在这里插入图片描述
表示/testD请求,如果每秒请求>=5,且异常率达到20%,则进行熔断。并且在接下来的三秒内访问都将自动返回。三秒后熔断关闭,访问正常。

3. 异常数

当资源近1分钟的异常数且超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若timeWindow小于60s,则结束熔断状态后仍可能在进入熔断状态。
时间窗口一定要大于等于60秒。
在这里插入图片描述
在这里插入图片描述
表示请求/testE,一分钟类出现5次异常,则发生熔断,而后70秒内都无法在访问,会自动返回。70秒后熔断关闭,恢复访问。

6. Sentinel 热点规则

1. 介绍与使用

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的Top K 数据,并对其访问进行限制。比如:

  • 商品ID为参数,统计一段时间内最常购买的商品ID并进行限流
  • 商品ID为参数,针对一段时间内频繁访问的用户ID进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅包含任店参数的资源调用生效。

之前学习的Hystrix,当某个方法出现问题了,就能找到对应的兜底降级方法,而Sentinel 有一套默认的兜底方法返回:Blocked by Sentinel (flow limiting)那么Sentinel如何自定义兜底方法呢?

Hystrix 自定义兜底方法是用的注解 @HystrixCommand 。Sentinel 使用的是 @SentinelResource 。

代码

/**
     *
     *  @SentinelResource(value = "testHotKey" ,blockHandler = "deal_testHotkey") 这里的testHotKey是可以随便取的。只要是唯一标识就可以
     *  blockHandler = "deal_testHotkey" 表示如果违背了sentinel的配置规则有方法deal_testHotkey进行处理。
     *
     * @param p1
     * @param p2
     * @return
     */
    @GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey" ,blockHandler = "deal_testHotkey")
    public String testHotKey(@RequestParam(value = "p1", required = false) String p1,
                             @RequestParam(value = "p2", required = false) String p2){

        return  "-----testHotKey";
    }


    public String deal_testHotkey(String p1, String p2, BlockException e){

        //sentinel 系统的默认提示: Blocked by sentinel (flow limiting)
        return "------deal_testHotkey, o(╥﹏╥)o";

    }

配置:
在这里插入图片描述

  • 资源名:即注解@SentinelResource里的Value值
  • 参数索引:即方法中的参数索引,本例中索引0 即 是 p1
  • 单机阈值:即每秒请求数
  • 统计窗口时长:即熔断时长

测试效果:当p1一直等于a且每秒访问超过一次后,再次访问,则返回我们自定义的方法:
在这里插入图片描述

2. 参数例外项

上述按理演示了第一个参数p1,当QPS超过了1秒1次点击后马上被限流。我们期望p1参数当它是某个特殊值时,他的限流值和平时不一样,加入当p1的值等于5时,他的阈值可以达到200。
在这里插入图片描述

总结:
@SentinelResource 处理的是Sentinel控制台配置的违规情况,有blockHandle方法配置的兜底处理。
但是运行时报错是不处理的,即RuntimeException。如 int age = 1/0,这个是java运行时报出的运行异常RuntimeException,@SentinelResource 不管。

7. Sentinel 系统规则(了解即可)

是对整个系统的限流规则。
在这里插入图片描述
在这里插入图片描述

8. @SentinelResource 详解

  1. 解决我们自定义的处理方法和业务代码耦合在一块不直观
    添加我们自定义阈值配置违背处理类 CustomerBlockHandler
package com.atguigu.springcloud.alibaba.myhandler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.springcloud.entities.CommonResult;

public class CustomerBlockHandler {

    public static CommonResult handlerException(BlockException exception){

        return new CommonResult(4444,"按客户自定义,global handlerException -----1");
    }

    public static CommonResult handlerException2(BlockException exception){

        return new CommonResult(4444,"按客户自定义,global handlerException -----2");
    }
}

controller层配置我们的处理类

@GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",blockHandlerClass = CustomerBlockHandler.class,blockHandler = "handlerException2")
    public CommonResult customerBlockHandler(){
        return new CommonResult(200,"按客户自定义",
                new Payment(2020L,"serial003"));
    }

他们的关系如下:
在这里插入图片描述
sentinel 主要有三个核心Api(了解即可)

  1. Sphu定义资源

  2. Tracer定义统计

  3. ContextUtil定义了上下文

  4. 解决我们代码异常类错误信息也能被自定义处理(fallback)
    在这里插入图片描述
    异常忽略:
    在这里插入图片描述

9. Sentinel 持久化

每次我们项目重启,Sentinel里面的配置内容就会消失。那么如何解决实现持久化呢?

  • 添加Pom 依赖
    在这里插入图片描述

  • yml配置
    在这里插入图片描述

  • 添加Nacos业务规则配置
    在这里插入图片描述

    • resouce:资源名称
    • limitApp:来源应用
    • grade:阈值类型,0表示线程数,1表示QPS
    • count:单机阈值
    • strategy:流控模式,0表示直接,1表示关联,2表示链路
    • controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示配对等待
    • clusterMode:是否集群
  • 测试,我们项目重启后登陆Sentinel,发现有我们的流控规则,无需在重新配置了,实现了配置的持久化
    在这里插入图片描述

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值