Spring Cloud Alibaba Sentinel 限流实例

什么是Sentinel

Sentinel是阿里巴巴开源的分布式系统的流量防卫组件,Sentinel 把流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 的主要特性

安装Sentinel

1、下载Sentinel控制台:

所有Sentinel版本的jar包下载地址:https://github.com/alibaba/Sentinel/releases

阿里sentinel github地址:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh.md

2、启动sentinel

到达指定目录后,输入java -jar sentinel-dashboard.jar,启动默认为8080端口

3、访问控制台

在浏览器上输入 http://localhost:8080  如果sentinel是1.6.0版本需要进行登录,默认账号:sentinel,密码:sentinel

输入地址后,显示如下图说明控制台启动成功:

编写sentinel实例

1、添加pom依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>0.9.0.RELEASE</version>
</dependency>

2、application.properties文件添加相应的配置信息

server.port=9977
#应用名称,在限流的控制台中显示
spring.application.name=sentinel-example
#限流控制台的地址和端口
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.eager=true

3、添加SentinelResource注解和创建对应的blockHandler类文件

SentinelTestController.java 

package com.example.wlztest.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.example.wlztest.util.SentinelExceptionUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class SentinelTestController {

    @SentinelResource(value = "sentinelTest", blockHandler = "exceptionHandler"
            , blockHandlerClass = { SentinelExceptionUtil.class }
            , fallback = "fallbackHandler")
    @RequestMapping(value = "/sentinelTest",method = RequestMethod.GET)
    @ResponseBody
    public String sentinelTest(long s){

        System.out.println("执行了sentinelTest方法");
        return "执行了sentinelTest方法";
    }

    // Fallback 函数,函数签名与原函数一致.
    public static String fallbackHandler(long s) {

        return String.format("调用了helloFallback方法", s);
    }
}

 SentinelExceptionUtil.java

package com.example.wlztest.util;

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

public class SentinelExceptionUtil {

    //异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
    public static String exceptionHandler(long s, BlockException ex) {
        ex.printStackTrace();
        return "调用SentinelExceptionUtil中的exceptionHandler方法" + s;
    }

    public static String exceptionHandler2(String str, BlockException ex) {
        ex.printStackTrace();
        return "调用SentinelExceptionUtil中的exceptionHandler2方法 " + str;
    }
}

以下为SentinelResource注解的属性说明

属性

作用

是否必填

value

资源名称

entryType

entry类型,标记流量的方向,取值IN/OUT,默认是OUT

blockHandler

处理BlockException的函数名称。函数要求:

1. 必须是 public

2.返回类型与原方法一致

3. 参数类型需要和原方法相匹配,并在最后加 BlockException 类型的参数。

4. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 blockHandlerClass ,并指定blockHandlerClass里面的方法。

blockHandlerClass

存放blockHandler的类。对应的处理函数必须static修饰,否则无法解析,其他要求:同blockHandler。

fallback

用于在抛出异常的时候提供fallback处理逻辑。fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。函数要求:

1. 返回类型与原方法一致

2. 参数类型需要和原方法相匹配,Sentinel 1.6开始,也可在方法最后加 Throwable 类型的参数。

3.默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定fallbackClass里面的方法。

fallbackClass【1.6】

存放fallback的类。对应的处理函数必须static修饰,否则无法解析,其他要求:同fallback。

defaultFallback【1.6】

用于通用的 fallback 逻辑。默认fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,以fallback为准。函数要求:

1. 返回类型与原方法一致

2. 方法参数列表为空,或者有一个 Throwable 类型的参数。

3. 默认需要和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定 fallbackClass 里面的方法。

exceptionsToIgnore【1.6】

指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。

exceptionsToTrace

需要trace的异常

Throwable

通过sentinel控制台配置限流规则

1、启动测试工程和sentinel控制台,可以看到下图,控制台中显示当前所启动的应用

2、点击簇点链路按钮,来到簇点链路的操作页面

3、选中一个资源点击流控按钮,配置流控条件

4、点击流控规则按钮,查看规则是否正确配置

5、上图我们将资源名为sentinelTest的埋点配置了QPS为3的流控条件,我们在浏览器访问 http://localhost:9977/sentinelTest?s=1  ,并快速刷新多次,页面内容由:

转变为:

说明成功触发流限规则,再看主控制台的实时监控页面,如红色标记,通过QPS最高为3,符合流限规则设置:

以上为使用sentinel进行流限控制的DEMO和演示流程。

Sentinel问题

1、单纯使用sentinel,规则无法进行持久化,在关闭、重启工程后,所配置的规则会丢失。需要自己进行额外的持久化操作,目前网上有一些接合Nacos或是本地文件进行规则初始化的用例。

2、使用Nacos进行规则初始化,如配置了下列依赖,会导致sentinel控制台的规则配置失效,只能读取Nacos中设置的规则,比较不灵活,原因是因为当前版本的sentinel控制台设置规则,不具备修改规则后对Nacos配置的的规则进行同步的能力。导致之后的配置新规则都需要在Nacos控制台中进行配置,然后推送给sentinel,造成sentinel控制台规则配合的作用下降。(此问题是本人暂无解决方法,如果有方法可以解决Sentinel控制台同步修改Nacos规则,麻烦给我留言)

        <!--sentinel指定nacos为数据源 -->
        <!--<dependency>-->
            <!--<groupId>com.alibaba.csp</groupId>-->
            <!--<artifactId>sentinel-datasource-nacos</artifactId>-->
            <!--<version>1.6.0</version>-->
        <!--</dependency>-->

3、结合本地文件进行Pull ,不能保证一致性、拉取过于频繁也可能会有性能问题等。

4、实时监控默认只能监控近6秒的数据,如果想监控长时间的数据需要自己进行改造,并进行数据持久化。

5、如果你的Sentinel控制台原本是1.6.0之前的版本,现在改成了1.6.0,出现控制台显示失败或数据异常的问题。请清除缓存,关闭浏览器再进行访问,个人猜想可能是因为1.6.0增加了登录功能的原因。

6、目前阿里有成熟的Sentinel产品,已经解决了持久化等问题,有需要也可以进行了解和借鉴。

发布了22 篇原创文章 · 获赞 4 · 访问量 3038

猜你喜欢

转载自blog.csdn.net/weixin_43841693/article/details/99945928