【SpringCloudAlibaba】Sentinel熔断限流工具的使用

一、前言

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。

Sentinel 的历史:

  • 2012 年,Sentinel 诞生,主要功能为入口流量控制。
  • 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
  • 2018 年,Sentinel 开源,并持续演进。
  • 2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出 C++ 原生版本,同时针对 Service Mesh 场景也推出了 Envoy 集群流量控制支持,以解决 Service Mesh 架构下多语言限流的问题。
  • 2020 年,推出 Sentinel Go 版本,继续朝着云原生方向演进。
  • 2021 年,Sentinel 正在朝着 2.0 云原生高可用决策中心组件进行演进;同时推出了 Sentinel Rust 原生版本。同时我们也在 Rust 社区进行了 Envoy WASM extension 及 eBPF extension 等场景探索。
  • 2022 年,Sentinel 品牌升级为流量治理,领域涵盖流量路由/调度、流量染色、流控降级、过载保护/实例摘除等;同时社区将流量治理相关标准抽出到 OpenSergo 标准中,Sentinel 作为流量治理标准实现。

--以上来自Sentinel官方文档;introduction | Sentinel

二、Sentinel 基本概念

1、资源

资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。

只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

2、规则

围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

三、在Linux下安装 Sentinel

1、安装包下载

https://github.com/alibaba/Sentinel/releases

2、拷贝到Linux服务器上并启动服务

启动命令:(指定端口号 8849)

nohup java -Dserver.port=8849 -Dcsp.sentinel.dashboard.server=localhost:8849 -Dproject.name=sentinel-dashboard -jar /home/springcloud/sentinel-dashboard-1.7.0.jar &

浏览器登录sentinel前端页面,地址:IP:8849

【注】访问失败的解决方法:

  • 查看 8849 端口号是否开放:firewall-cmd --query-port=8849/tcp
  • 打开端口:firewall-cmd --zone=public --add-port=8849/tcp --permanent
  • 重启防火墙:firewall-cmd --reload

3、重新登录,用户名密码都是 sentinel

四、Springcloud 整合 Sentinel

1、pom.xml中引入依赖包

java 复制代码
        <properties>
        <java.version>8</java.version>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.boot.version>2.3.2.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR9</spring.cloud.version>
        <spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
        </properties>



       <!-- sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>${spring.cloud.alibaba.version}</version>
        </dependency>

2、在application.yml中添加配置,指定Sentinel的服务地址

java 复制代码
spring:
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.1.233:8849

3、创建测试接口

java 复制代码
package com.example.springclouduser.controller;

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

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/queryUserInfoById/{userId}")
    public String queryUserInfoById(@PathVariable Long userId) {
         return "接口名:[queryUserInfoById] 调用成功,用户ID:" + userId;
    }

}

4、浏览器调用接口,在 Sentienl 的簇点链路中就会显示

到此,证明本地已经和 Sentinel 服务连接上了。

五、Sentinel各个功能的使用

1、流控规则

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

1.1 QPS + 直接 + 快速失败

当接口 /user/queryUserInfoById 每秒访问数超过3个,直接报错。

测试结果:

当 QPS 超过阈值,报错:

1.2 QPS + 关联 + 快速失败

当关联的资源 /user/secondMethod 接口每秒访问数超过3个,会使 /user/queryUserInfoById 接口限流。

测试流程:

(1)使用 Jmeter 压测工具,每秒钟并发发送四个请求

此时 接口 /user/secondMethod 的 QPS 阈值超过 3,再访问接口 /user/queryUserInfoById 时被限流:

1.3 QPS + 链路 + 快速失败

只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就可以限流)[api级别的针对来源]

/user/queryUserInfoById 接口属于 sentinel_spring_web_context 链路下,因为入口资源填写 sentinel_spring_web_context。

再次访问 /user/queryUserInfoById 接口发现被限流:

1.4 QPS + 直接 + Warm Up

请求QPS从设定的阈值/3开始,经预热时长逐渐升至设定的QPS阈值

如下图所示,QPS开始时为 3/coldFactor = 3/3 = 1 (冷因子coldFactor默认为3)

经过5秒后,QPS 达到最终设定的阈值3。

1.5 QPS + 直接 + 排队等待

接口 queryUserInfoById 每秒访问1次,多余的请求排队等待,之后匀速访问接口,超时时间为2秒。

为接口queryUserInfoById加上日志,查看日志打印,是否相隔1秒后调用。

java 复制代码
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/queryUserInfoById/{userId}")
    public String queryUserInfoById(@PathVariable Long userId) {
         String message = "接口名:[queryUserInfoById] 调用成功,用户ID:" + userId;
         log.info("当前线程:[{}]", Thread.currentThread().getName());
         return message;
    }

}

测试结果:

以上每种模式的例子只找了一种,感兴趣的同学可以试试其他的模式;


2、降级规则

2.1 RT:平均响应时间

当资源的平均响应时间超过阈值(DegradeRule 中的 count,以 ms 为单位)之后,资源进入准降级状态。如果接下来 1s 内持续进入 5 个请求(即 QPS >= 5),它们的 RT 都持续超过这个阈值,那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。

**【注】**RT默认最大4900ms,超过此阈值的也会算作 4900ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置

测试过程:

(1)创建降级规则:当RT= 3000ms,时间窗口为 5s 。

(2)修改接口,添加 6s的响应时间

java 复制代码
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/queryUserInfoById/{userId}")
    public String queryUserInfoById(@PathVariable Long userId) {
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String message = "接口名:[queryUserInfoById] 调用成功,用户ID:" + userId;
         log.info("当前线程:[{}]", Thread.currentThread().getName());
         return message;
    }
}

(3)jmeter模拟每秒10个请求的并发环境,调用接口,发现接口返回报错:Blocked by Sentinel(flow limiting)

(4)注释掉响应时间6s,同样使用jmeter调用接口,发现接口返回正常。

2.2 异常比例

当资源的每秒异常总数占通过量的比值超过阈值(阈值范围是 [0.0, 1.0],代表 0% - 100%。)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。

2.3 异常数

当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。

3、热点规则

热点规则限流只支持 QPS 模式,也只有 QPS模式下才叫热点;

参数索引:调用方法所传参数的索引,0代表第一个参数,1代表第二个参数,以此类推;

单机阈值以及统计窗口时长表示在此窗口时间内,访问数超过阈值数量就触发限流。

4、系统规则

系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效 。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。

系统规则支持以下的模式:

  • Load 自适应 (仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt估算得出。设定参考值一般是 CPU cores * 2.5
  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

相关推荐
启山智软7 分钟前
【中大企业选择源码部署商城系统】
java·spring·商城开发
我真的是大笨蛋10 分钟前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化
怪兽源码38 分钟前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
恒悦sunsite44 分钟前
Redis之配置只读账号
java·redis·bootstrap
梦里小白龙1 小时前
java 通过Minio上传文件
java·开发语言
人道领域1 小时前
javaWeb从入门到进阶(SpringBoot事务管理及AOP)
java·数据库·mysql
sheji52611 小时前
JSP基于信息安全的读书网站79f9s--程序+源码+数据库+调试部署+开发环境
java·开发语言·数据库·算法
毕设源码-邱学长1 小时前
【开题答辩全过程】以 基于Java Web的电子商务网站的用户行为分析与个性化推荐系统为例,包含答辩的问题和答案
java·开发语言
摇滚侠1 小时前
Java项目教程《尚庭公寓》java项目从开发到部署,技术储备,MybatisPlus、MybatisX
java·开发语言
€8112 小时前
Java入门级教程24——Vert.x的学习
java·开发语言·学习·thymeleaf·数据库操作·vert.x的路由处理机制·datadex实战