一、Sentinel简介

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护等多个维度来帮助您保障微服务的稳定性。

主要特性:

Sentinel-features-overview

二、安装Sentinel控制台

下载链接:https://github.com/alibaba/Sentinel/releases/tag/1.7.0 选择sentinel-dashboard-1.7.0.jar下载

进去jar包目录启动:

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.0.jar

默认用户名密码为:sentinel sentinel

二、项目示例

此项目以2.1.1版本Spring-cloud + Dubbo + Nacos初试环境为基础。

实现功能:简单限流、熔断,Nacos动态配置限流规则

1、 添加依赖

provider 项目添加依赖:

 <!--sentinel依赖 2.1.1 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--sentinel-nacos 1.7.0 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

2、nacos新增限流规则配置

[
    {
        "resource": "test",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

新建配置选择json格式 

配置文件解释:

  • resource:资源名,即限流规则的作用对象
  • limitApp:流控针对的调用来源,若为 default 则不区分调用来源
  • grade:限流阈值类型(QPS 或并发线程数);0代表根据并发数量来限流,1代表根据QPS来进行流量控制
  • count:限流阈值
  • strategy:调用关系限流策略
  • controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队)
  • clusterMode:是否为集群模式

3、配置文件修改

修改provider项目的bootstrap.yml

spring:
  application:
    name: @artifactId@
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
      datasource:
        ds:
          nacos:
            server-addr: http://*****
            groupId: DEFAULT_GROUP
            dataId: provider-sentinel
            namespace: 725d62dc-11f8-451d-ac7e-04427536de08
            rule-type: flow
  • sentinel.transport.dashboard: sentinel控制台地址
  • server-addr:nacos地址
  • groupId:规则配置的group
  • dataId:  规则配置的dataId
  • namespace: 命名空间(有多个namespace时必须有namespace配置,否则限流规则失败)
  • rule-type:规则类型,flow:限流规则

4、接口修改(基于注解)

try-catch风格的API可以实现限流,但是对代码侵入性太高,推荐使用注解的方式来实现;Sentinel API 方式可在王芳文档中查看。

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

@SentinelResource注解:用于定义资源,对有该注解的接口进行流量控制和熔断

@SentinelResource(value = "test",
            blockHandler = "handleException",
            blockHandlerClass = {ExceptionUtil.class},
            fallback = "helloFallback",
            fallbackClass = {ExceptionUtil.class})
    @Override
    public Result get(String s) {
        //测试熔断
//        throw new RuntimeException();
        return new Result(s);
    }
ExceptionUtil 
public class ExceptionUtil {

    public static Result handleException(String s, BlockException ex) {
        // Do some log here.
//        ex.printStackTrace();
        System.out.println("被限流,无法访问接口");
        return new Result("被限流,无法访问接口");
    }

    /**
     * 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
     * fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
     *
     * @param s
     * @return
     */
    public static Result helloFallback(String s) {
        System.out.println("熔断功能被开启");
        return new Result("熔断功能被开启");
    }
}

@SentinelResource 注解包含以下属性:

  • value:资源名称,必需项(不能为空)
  • entryType:entry 类型,可选项(默认为 EntryType.OUT
  • blockHandler / blockHandlerClassblockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • fallback:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
    • 返回值类型必须与原函数返回值类型一致;
    • 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
    • fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
    • 返回值类型必须与原函数返回值类型一致;
    • 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
    • defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

注:1.6.0 之前的版本 fallback 函数只针对降级异常(DegradeException)进行处理,不能针对业务异常进行处理

特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandlerfallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出(若方法本身未定义 throws BlockException 则会被 JVM 包装一层 UndeclaredThrowableException)。

5、验证

1、验证限流

顺序启动provider和consumer,观察sentinel控制台

查看流控规则,发现配置中心的流控规则被加载到了provider

请求接口http://localhost:8003/snaPup/get  快速刷新时会被限流

2、验证熔断

请求接口发现:

三、参考文档

Sentinel官方文档

https://blog.csdn.net/qq_38157516/article/details/100122519

https://blog.csdn.net/noaman_wgs/article/details/103328793

完整代码:https://github.com/menglinjie/spring-cloud-alibaba-example

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐