[03] Spring Cloud Alibaba 入门_Sentinel 熔断与限流

一、Sentinel 简介

Sentinel 是分布式系统的流量防卫兵,从流量控制、熔断降级、负载保护等多个维度保护系统的稳定性。

它不再需要配置很多东西,在其图形化界面进行设置即可。Hystrix 加量不加价的升级版

特征包括:

  • 应用场景丰富:消息削峰填谷、集群流量控制、实时熔断
  • 实时监控
  • 引入依赖简单配置即可使用
  • 定制规则管理、适配动态数据源

Sentinel 主要分为两部分:

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

二、下载安装

官网地址

可以看到目前最新版是 1.8.2

在这里插入图片描述

往下滑,下载 jar 包

在这里插入图片描述

下载完成后放到没有中文和空格的目录下,该目录下启动 cmd 窗口

前提:

  • 配置好 JDK
  • 8080 端口没被占用

cmd 窗口执行 java -jar sentinel-dashboard-1.8.2.jar

在这里插入图片描述

启动成功后进行访问 http://localhost:8080

在这里插入图片描述
账号密码同为 sentinel

在这里插入图片描述

三、 当前项目结构介绍

当前项目中包含十二个模块:

在这里插入图片描述

  • 公有API:cloud-api-commons
  • 服务提供者: cloud-provider-payment8001(增加 Sleuth)/8002 (端口号8001 和 8002 )
  • 服务消费者(restTemplate): cloud-consumer-order80 (端口号80 ,增加 Sleuth)
  • 服务消费者(OpenFeign): cloud-consumer-feign-order80(端口号80 )
  • 注册中心 Eureka: cloud-eureka-server7001(端口号7001 )
  • 使用断路器实现的服务提供者 (Hystrix):cloud-provider-hystrix-payment8001(端口号8001)
  • 使用断路器实现的服务消费者(Hystrix):cloud-consumer-feign-hystrix-order80(端口号80)
  • 服务监控(hystrixDashboard):cloud-consumer-hystrix-dashboard9001(端口号9001)
  • 网关(Gateway):cloud-gateway-gateway9527(端口号9527)


  • 服务提供者(基于Nacos):cloudalibaba-provider-payment9001(端口号9001)
  • 服务消费者(基于Nacos):cloudalibaba-consumer-nacos-order83(端口号83)
  • Nacos服务配置中心:cloudalibaba-config-nacos-client3377(端口号3377)

前文链接: https://blog.youkuaiyun.com/weixin_42547014/article/details/120334570
项目源码: https://gitee.com/zhangchouchou/spring-cloud-demo

四、项目中添加 Sentinel

1. 添加 Module,修改 POM

以 Maven 方式创建新的模块 cloudalibaba-sentinel-service8401,在 POM 中添加引用

    <dependencies>
        <dependency>
            <groupId>org.zjh.springclouddemo</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</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-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>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.11</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2. 新增 YML 配置文件

在这里插入图片描述

server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719  #默认8719,应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用HttpServer

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

在这里插入图片描述

在这里插入图片描述

3. 添加启动类

@EnableDiscoveryClient
@SpringBootApplication
public class SentinelApplication {
    public static void main(String[] args) {
        SpringApplication.run(SentinelApplication.class, args);
    }
}

4. 添加 controller

@RestController
@Slf4j
public class SentinelController {
    @GetMapping("/testA")
    public String testA() {
        return "------testA";
    }

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

}

5. 测试

启动 Nacos

在这里插入图片描述
在这里插入图片描述
启动成功后访问 http://192.168.44.1:8848/nacos/index.html 进行检验

启动 Sentinel

Sentinel 的 jar 包目录下 cmd 窗口执行 java -jar sentinel-dashboard-1.8.2.jar

启动刚刚编写的服务

访问 Sentinel 界面

因为 Sentinel 采用的懒加载,所以界面应该为空

在这里插入图片描述

访问测试接口

访问 http://localhost:8401/testAhttp://localhost:8401/testB

在这里插入图片描述

刷新 Sentinel 界面

在这里插入图片描述

五、操作介绍

1、流控规则

QPS

控制每秒的访问次数和处理请求的线程数

在这里插入图片描述

对 testA 接口进行流控,设置每秒访问一次,超过直接降级处理

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

设置完以后访问 http://localhost:8401/testA 进行测试,连续刷新后返回降级处理内容

在这里插入图片描述

线程

对规则进行修改

在这里插入图片描述
在这里插入图片描述

修改接口代码,让他新建线程

在这里插入图片描述

重启服务后多次刷新访问 http://localhost:8401/testA

注:Sentinel没有持久化,监控的服务重启后对应的监控规则就没有了

在这里插入图片描述

关联

当与A关联的资源B达到阈值后,就限流自己

修改流控规则:当关联资源/testB的QPS阀值超过1时,就限流/testA的REST访问。

在这里插入图片描述

使用 Postman 模拟并发密集访问 testB

在这里插入图片描述
postman 里新建多线程集合组,将请求保存到集合组

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

此时访问 testA

在这里插入图片描述

预热

用5秒钟的时间达到最大访问值10

快速刷新 testA ,刚开始会出现降级结果,慢慢就不会出现了。

比如秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是为了保护系统,可慢慢的把流量放进来,慢慢的把阈值增长到设置的阈值。

在这里插入图片描述

排队等待

匀速排队,让请求以均匀的速度通过,阈值类型必须设置成QPS,否则无效。

设置 /testB 每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。

在这里插入图片描述

修改 testB ,增加打印语句

@GetMapping("/testB")
public String testB() {
log.info(Thread.currentThread().getName()+"\t ...testB");
return "------testB";
}

在这里插入图片描述
在这里插入图片描述

2、熔断降级

官网地址

在这里插入图片描述
在这里插入图片描述

RT(平均响应时间,秒级)
  • 平均响应时间 (DEGRADE_GRADE_RT):超过阈值 且 时间窗口内的请求>=5,两个条件同时满足后触发降级,窗口期过后关闭断路器
  • RT 最大4900 ms,更大的需要通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。
异常比例(秒级)
  • QPS>=5且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级
异常数(分钟级)
  • 异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如:调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其他的资源而导致级联错误。

当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出DegradeException)。

Sentinel的断路器是没有半开状态的
半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。具体可以参考Hystrix

测试

添加测试接口

@GetMapping("/testD")
public String testD(){
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        log.info("testD 测试RT");
        return "------testD";
}

在这里插入图片描述

使用 Jmeter 压测

Windows系统Jmeter下载安装教程

添加线程组

在这里插入图片描述

添加 HTTP 请求

在这里插入图片描述
启动压测后访问 testD

在这里插入图片描述
永远一秒钟打进来10个线程(大于5个了)调用testD,我们希望200毫秒处理完本次任务,
如果超过200毫秒还没处理完,在未来1秒钟的时间窗口内,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电了
后续停止jmeter,没有这么大的访问量了,断路器关闭(保险丝恢复),微服务恢复OK

异常比例

在这里插入图片描述
修改 testD 接口

在这里插入图片描述
新增规则

在这里插入图片描述
调整压测

在这里插入图片描述

正常访问报错,by zero

在这里插入图片描述

熔断处理后:

在这里插入图片描述

异常数

在这里插入图片描述
时间窗口一定要大于等于60秒

在这里插入图片描述
刷新5次后降级处理

3、热点规则

在这里插入图片描述

官网地址

在这里插入图片描述

添加新的接口

	@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) {
        //int age = 10/0;
        return "------testHotKey";
    }

    //兜底方法
    public String deal_testHotKey (String p1, String p2, BlockException exception){
        return "------testHotKey 兜底方法";
    }

添加完接口后重启服务,先刷新 Sentinel 界面,然后访问 http://localhost:8401/testHotKey?p1=abc

在这里插入图片描述

添加规则

在这里插入图片描述
添加完成后快速刷新访问

在这里插入图片描述

测试

若使用 http://localhost:8401/testHotKey?p1=abc&p2=33 访问,可返回兜底方法

在这里插入图片描述

若仅带参数 p2 访问 http://localhost:8401/testHotKey?p2=abc ,不会返回兜底方法

在这里插入图片描述

其他规则

在这里插入图片描述

4、系统规则

在这里插入图片描述
在这里插入图片描述

六、全局兜底方法设置

启动类加上注解

在这里插入图片描述

1. 创建 customerBlockHandler 类用于自定义限流处理逻辑

方法必须是public static修饰的

package org.zjh.springcloud.helper;

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

public class CustomerBlockHandler {
    public static CommonResult handleException(BlockException exception){
        return new CommonResult(2020,"自定义限流处理信息.... CustomerBlockHandler --- 1");
    }

    public static CommonResult handleException2(BlockException exception){
        return new CommonResult(2020,"自定义限流处理信息.... CustomerBlockHandler --- 2");
    }
}

2. 创建新的测试接口

    @GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",
            blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handleException2")
    public CommonResult customerBlockHandler(){
        return new CommonResult(200,"按客戶自定义",new User(11,"姓名","18320988374","男"));
    }

在这里插入图片描述

3. 测试

访问 http://localhost:8401/rateLimit/customerBlockHandler

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值