• Spring Cloud Alibaba系列(五)sentinel实现服务限流降级


    一、sentinel是什么

    sentinel的官方名称叫分布式系统的流量防卫兵。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。在Spring Cloud项目中最开始我们使用的是Hystrix,目前已停止更新了。现在Spring Cloud官方推荐的是rensilience4j。当然还有我们今天学习的sentinel。

    Sentinel 具有以下特征:

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

    二、sentinel实现限流

    2.1 安装sentinel控制台

    这里我们直接下载jar包即可,下载后通过命令行启动:

    java -jar sentinel-dashboard-1.7.2.jar
    
    • 默认端口:8080
    • 默认用户名:sentinel
    • 默认密码:sentinel

    启动成功后,我们浏览器访问http://localhost:8080,出现如下界面。

    2.2 微服务继承sentinel

    • 引入sentinel依赖
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
    • 添加sentinel的相关配置
    server:
      port: 7003
    spring:
      application:
        name: sentinel-provider
      cloud:
    	nacos:
          discovery:
            server-addr: 127.0.0.1:8848
        sentinel:
          transport:
            dashboard: 127.0.0.1:8080
    
    • 提供个接口用来测试限流
    @SpringBootApplication
    public class SentinelApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SentinelApplication.class, args);
        }
    }
    
    @RestController
    class TestController{
        @GetMapping("/test")
        public String test(){
            return "hello! sentinel!";
        }
    }
    

    我们请求几次这个接口后,打开sentinel控制台,就可以实时监控到这个sentinel-provider服务接口调用情况了。

    2.3 配置限流规则

    我们这里做一个简单的规则配置:

    • 阀值类型:QPS

    • 单机阀值:2

    意思就是:该接口每秒最多允许进入两个请求。

    点击新增后,在流控规则里发现了一条规则:

    现在,我们继续请求3次这个接口。第三次响应的内容如下:

    Blocked by Sentinel (flow limiting)
    

    我们打开控制台发现拒绝了一条请求。

    三、Sentinel规则介绍

    不管是限流还是降级,它都是按照某种规则进行的,下面具体介绍一下sentinel支持的几种规则。

    3.1 流控规则

    流量控制,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标,当达到指定的阈值时

    对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

    资源名:唯一名称,默认是请求路径,可自定义

    针对来源:指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制

    阈值类型/单机阈值

    • QPS(每秒请求数量): 当调用该接口的QPS达到阈值的时候,进行限流

    • 线程数:当调用该接口的线程数达到阈值的时候,进行限流

    3.2 降级规则

    降级规则就是当满足什么条件时,对服务降级——即将请求转发到另外接口上,这个接口与业务无关,只是为了保证系统的完整性。

    • RT(平均响应时间) :当资源的平均响应时间超过阈值(以 ms 为单位)之后,资源进入准降级状态。如果接下来 1s 内持续进入 5 个请求,它们的 RT都持续超过这个阈值,那么在接下的时间窗口(以 s 为单位)之内,就会对这个方法进行服务降级。

      注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。

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

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

    3.3 热点规则

    热点规则允许将规则具体到参数上。

    我们用个例子来看看效果。

    • 编写接口
    @GetMapping("/myTest")
    @SentinelResource("test3")
    public String test123(String name,String age){
        return  name + "----"+ age;
    }
    
    • 添加规则

    • 运行效果

    结果显示,第一个参数被限流了,而第二个参数正常。

    3.4 系统规则

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

    系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量 (进入应用的流量) 生效。

    • Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计算得出。设定参考值一般是 CPU cores * 2.5。

    • RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。

    • 线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。

    • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

    • CPU使用率:当单台机器上所有入口流量的 CPU使用率达到阈值即触发系统保护。

    3.5 授权规则

    很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源问控制的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过:

    • 若配置白名单,则只有请求来源位于白名单内时才可通过;

    • 若配置黑名单,则请求来源位于黑名单时不通过,其余的请求通过。

    流控应用:sentinel提供了RequestOriginParser来处理接口来源。

    我们运行abc来源的请求访问/test接口。

    @Component
    class requestOrigin implements RequestOriginParser{
    
        @Override
        public String parseOrigin(HttpServletRequest httpServletRequest) {
            String server = httpServletRequest.getParameter("server");
            return server;
        }
    }
    

    我们请求http://localhost:7003/test?server=abc 和 http://localhost:7003/test?server=ab来分别看看效果。

    @SentinelResource的使用

    @SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。

    主要参数有以下几个

    属性 作用
    value 资源名称
    entryType entry类型,标记流量的方向,取值IN/OUT,默认是OUT
    blockHandler 处理BlockException的函数名称,函数要求:1. 必须是 public;2.返回类型 参数与原方法一致;3. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置blockHandlerClass ,并指定blockHandlerClass里面的方法。
    blockHandlerClass 存放blockHandler的类,对应的处理函数必须static修饰。
    fallback 1. 返回类型与原方法一致;2. 参数类型需要和原方法相匹配;3. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置fallbackClass
    fallbackClass 存放fallback的类。对应的处理函数必须static修饰。
    defaultFallback 若同时配置了 fallback 和 defaultFallback,以fallback为准。
    exceptionsToIgnore 指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。
    exceptionsToTrace 需要trace的异常

    @sentinelResource可结合blockHandler用于限流处理,结合fallback用于降级处理。具体规则可通过sentinel控制台配置,具体我就不演示了,在下一章内容中,我会分别演示限流和降级的应用。

    public class MySentinelResource {
    
        @SentinelResource(value="message",blockHandler="blockHandler",fallback="fallback")
        public String message(String str){
            if(StringUtils.isBlank(str)){
                throw new RuntimeException();
            }
            return str;
        }
        /**
         * 限流处理
         * @param str
         * @param ex
         * @return
         */
        public String blockHandler(String str, BlockedException ex){
            return str + "--"+ ex;
        }
        /**
         * 降级处理
         * @param str
         * @return
         */
        public String fallback(String str){
            return null;
        }
    }
    

    代码示例

    giteehttps://gitee.com/zhixie/spring-cloud-alibaba-learning/tree/master/sentinel-server

    githubhttps://github.com/binzh303/spring-cloud-alibaba-learning/tree/master/sentinel-server

  • 相关阅读:
    iBatis.Net(4):DataMapper API
    【转】一步一步学Linq to sql(七):并发与事务
    【转】一步一步学Linq to sql(五):存储过程
    iBatis.Net(5):Data Map
    【转】一步一步学Linq to sql(三):增删改
    iBatis.Net(6):Data Map(深入)
    【转】一步一步学Linq to sql(四):查询句法
    【转】一步一步学Linq to sql(二):DataContext与实体
    .NET自动字符编码识别程序库 NChardet
    SQL UNIQUE Constraint
  • 原文地址:https://www.cnblogs.com/zhixie/p/13202737.html
Copyright © 2020-2023  润新知