微服务06:Sentinel(哨兵)限流应用实践

Sentinel简介

我们如何在这些业务流量变化无常的情况下,保证各种业务安全运营,系统在任何情况下都不会崩溃呢?我们可以在系统负载过高时,采用限流、降级和熔断,三种措施来保护系统,由此一些流量控制中间件诞生。例如Sentinel。

Sentinel概述

Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。
Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景, 例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

Sentinel核心分成两个部分

核心库(java客户端):能够运行于所有 Java 运行时环境,同时对Dubbo /Spring Cloud 等框架也有较好的支持。

控制台(Dashboard):基于spring boot开发,打包以后直接运行

安装Sentinel服务

Sentinel 提供一个轻量级的控制台, 它提供机器发现、单机资源实时监控以及规则管理等功能,其控制台安装步骤如下:
第一步:打开sentinel下载网址 下载Jar包(可以存储到一个sentinel目录),如图所示:

https://github.com/alibaba/Sentinel/releases在这里插入图片描述

第二步:在sentinel对应目录,打开命令行(cmd),启动运行sentinel

 java
-Dserver.port=8180
-Dcsp.sentinel.dashboard.server=localhost:8180
-Dproject.name=sentinel-dashboard
-jar
D:\TCGBIV\TOOLS\sentinel-dashboard-1.8.0.jar

检测启动过程,如图所示:

在这里插入图片描述

 访问Sentinal服务

第一步:假如Sentinal启动ok,通过浏览器进行访问测试,如图所示:

在这里插入图片描述

 第二步:登陆sentinel,默认用户和密码都是sentinel,登陆成功以后的界面如图所示:在这里插入图片描述

 Sentinel限流入门

限流的目的防止恶意请求流量、恶意攻击,或者防止流量超过系统峰值。

Sentinel集成

第一步:Sentinel 应用于服务消费方(Consumer),在消费方添加依赖如下

        <!--Sentinel 应用于服务消费方(Consumer),在消费方添加依赖如下:-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--spring对Sentinel的监控,会打开一些监控的断点,深度开发必用-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

第二步:打开服务消费方配置文件application.yml,添加sentinel配置,代码如下:

spring:
  cloud:
    sentinel:
      transport:
         port: 8099 #跟sentinel控制台交流的端口,随意指定一个未使用的端口即可
         dashboard: localhost:8180 # 指定sentinel控制台地址。

 第三步:启动服务提供者,服务消费者,然后在浏览器访问消费者url,如图所示:

在这里插入图片描述

 第四步:刷新sentinel 控制台,检测服务列表,如图所示:在这里插入图片描述

 Sentinel限流快速入门

我们设置一下指定接口的流控(流量控制),QPS(每秒请求次数)单机阈值为1,代表每秒请求不能超出1次,要不然就做限流处理,处理方式直接调用失败。

第一步:选择要限流的链路,如图所示:

在这里插入图片描述

 第二步:设置限流策略,如图所示:在这里插入图片描述

 第三步:反复刷新访问消费端端服务,检测是否有限流信息输出,如图所示:在这里插入图片描述

Sentinel流控规则分析

阈值类型分析

  • QPS(Queries Per Second):当调用相关url对应的资源时,QPS达到单机阈值时,就会限流。

  • 线程数:当调用相关url对应的资源时,线程数达到单机阈值时,就会限流。

设置限流模式

Sentinel的流控模式代表的流控的方式,默认【直接】,还有关联,链路。

直接模式

Sentinel默认的流控处理就是【直接->快速失败】。

在这里插入图片描述

关联模式

当关联的资源达到阈值,就限流自己。例如设置了关联资源为/ur2时,假如关联资源/url2的qps阀值超过1时,就限流/url1接口(是不是感觉很霸道,关联资源达到阀值,是本资源接口被限流了)。这种关联模式有什么应用场景呢?我们举个例子,订单服务中会有2个重要的接口,一个是读取订单信息接口,一个是写入订单信息接口。在高并发业务场景中,两个接口都会占用资源,如果读取接口访问过大,就会影响写入接口的性能。业务中如果我们希望写入订单比较重要,要优先考虑写入订单接口。那就可以利用关联模式;在关联资源上面设置写入接口,资源名设置读取接口就行了;这样就起到了优先写入,一旦写入请求多,就限制读的请求。例如:

在这里插入图片描述

 在这里插入图片描述

 链路模式

假如是sentinel 1.7.2以后版本,Sentinel Web过滤器默认会聚合所有URL的入口为sentinel_spring_web_context,因此单独对指定链路限流会不生效,需要在application.yml添加如下语句来关闭URL PATH聚合,例如:

sentinel:
     web-context-unify: false

链路模式只记录指定链路入口的流量。也就是当多个服务对指定资源调用时,假如流量超出了指定阈值,则进行限流。被调用的方法用@SentinelResource进行注解,然后分别用不同业务方法对此业务进行调用,假如A业务设置了链路模式的限流,在B业务中是不受影响的。例如现在设计一个业务对象,代码如下(为了简单,可以直接写在启动类内部):

@Service
public class ConsumerService{
    //标注这是一个限流链路的叶子节点。
    //一般来说,每一个URL会是一个节点。但是,我们可以使用@SentinelResource注解,
    //来让某一个方法也会成为链路中的子节点"()"中的内容将作为链路节点的名
    @SentinelResource("doGetResource")
    public String doGetResource(){
        return "doGetResource";
    }
}

接下来我们在/consumer/doRestEcho1对应的方法中对ConsumerService中的doGetResource方法进行调用(应用consumerService对象之前,要先在doRestEcho01方法所在的类中进行consumerService值的注入)。例如:

    @RestController
    public class ConsumerController{ 
        @Autowired
        private   ConsumerService consumerService;
       
      //http://ip:port/consumer/doRestEcho1
      @GetMapping("/consumer/doRestEcho1")
      public String doRestEcho1(){

            //第一次加入doGetResource方法
            consumerService.doGetResource();
            ...
        }

        @GetMapping("/consumer/doRestEcho2")
        public String doRestEcho2 (){
            
            //第二次加入doGetResource方法
            consumerService.doGetResource();
          ...
        }
    }

其路由规则配置如下:

 

 

 增加了限流对象的链路会被限流

如果不添加限流路径的对象,仅对对象进行限流:双方都会被限流

 

预热

阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值。设置的单机阈值为100,预热时长为10s。那么初始并发就是100/3=33。经过10s,并发阈值增加到100

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

在这里插入图片描述

 排队等待

从字面上面就能够猜到,匀速排队,让请求以均匀的速度通过,阈值类型必须设成QPS,否则无效。比如有时候系统在某一个时刻会出现大流量,之后流量就恢复稳定,可以采用这种排队模式,大流量来时可以让流量请求先排队,等恢复了在慢慢进行处理。超过设定的时间才会设置为超时

在这里插入图片描述

小结

限流模式:限制某个服务的特定时常内的并发数量

关联模式:当关联的某个服务达到阈值,就会限制自身的的服务资源,将多余资源供给给对方。

链路限流的作用:只限制某一个簇点链路中的特定服务做限制,且不影响其他链路中的相同服务

预热:初始并发只有并发上限/coldFactor(默认为3),即默认33%的初始并发,进过设定数组的量后逐渐增加到上线的并发量

排队等待,设定固定的并发值,超过量级之后才会排队等待,排队时间超过等待时常才会超时无效

sentinel是什么?(阿里推出的一个流量控制平台,防卫兵)

 类似Sentine的产品你知道什么?(hystrix一代微服务产品)

 你了解哪些限流算法?(计数器,令牌桶,漏斗算法,滑动窗口算法...)

sentinel的默认限流算法是什么(滑动窗口算法)

 你了解sentinel中的阈值应用类型吗?(线程数,ops)

 默认的限流模式有哪些?(直连,关联,链路)

限流效果有哪些(快速失败,预热,排队)

sentinel为什么可以进行限流?

访问web时会有拦截器对url进行拦截,根据控流规则对流量进行控制

熔断

,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。
Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

慢调用比例在这里插入图片描述

在这里插入图片描述

 慢调用熔断设置的参数说明:

最大RT设置的阈值,响应时间超过该阈值标记为不稳定状态应用
比例阈值慢调用占所有的调用比例,范围0~1
熔断时长如果发生熔断,停止服务的时间长度
最小请求数允许通过的最小请求数,该数量内不熔断

熔断:当响应超时时,掐断传输链接。在设定的时间内,无法再访问服务器。若未指定异常,后台会通报异常DegradeException(降级异常),熔断时长为用户自定义设置

探测:当熔断过了定义的熔断时长,状态由熔断变成探测

关闭:如果接下来的请求小于Rt,说明慢调用已经恢复,结束熔断,状态由探测转为关闭,如果接下来一个请求大于RT,说明慢调用未恢复,继续熔断,熔断时长保持一致

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

系统提供了默认的异常处理机制,假如默认处理机制不满足我们需求,我们可以自己进行定义。定义方式上可以直接或间接实现BlockExceptionHandler接口,并将对象交给spring管理。

异常比例

当资源的每秒请求数大于等于最小请求数,并且异常总数占通过量的比例超过比例阈值时,资源进入降级状态。

属性说明
异常比例阈值发生的异场请求数/请求总数(0~1)
熔断时长持续停止访问的时间
最小请求数运行通过的最小请求数,在此数量内不会熔断

异常比例中的状态分析如下:

熔断(OPEN):当请求数大于最小请求并且异常比例大于设置的阈值时触发熔断,熔断时长由用户设置。
探测(HALFOPEN):当超过熔断时长时,由熔断(OPEN)转为探测(HALFOPEN)
关闭(CLOSED):如果接下来的一个请求未发生错误,说明应用恢复,结束熔断,状态由探测(HALF_OPEN)变更为关闭(CLOSED)。如果接下来的一个请求继续发生错误,说明应用未恢复,继续熔断,熔断时长保持一致。

异常数量

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

属性说明
异常比例阈值发生的异场请求数
熔断时长持续停止访问的时间
最小请求数运行通过的最小请求数,在此数量内不会熔断

基于异常数的状态分析如下:

熔断(OPEN):当请求数大于最小请求并且异常数量大于设置的阈值时触发熔断,熔断时长由用户设置。
探测(HALFOPEN):当超过熔断时长时,由熔断(OPEN)转为探测(HALFOPEN)
关闭(CLOSED):如果接下来的一个请求未发生错误,说明应用恢复,结束熔断,状态由探测(HALF_OPEN)变更为关闭(CLOSED)如果接下来的一个请求继续发生错误,说明应用未恢复,继续熔断,熔断时长保持一致。

熔断异常自定义处理

@Component
public class ServiceBlockExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        //response.setStatus(601);
        //设置响应数据的编码
        response.setCharacterEncoding("utf-8");
        //告诉客户端要响应的数据类型以及客户端以什么编码呈现数据
        response.setContentType("text/html;charset=utf-8");
        PrintWriter pw=response.getWriter();
        Map<String,Object> map=new HashMap<>();
        if(e instanceof DegradeException){//降级、熔断
            map.put("status",601);
            map.put("message", "服务被熔断了!");
        }else if(e instanceof FlowException){
            map.put("status",602);
            map.put("message", "服务被限流了!");
        }else{
            map.put("status",603);
            map.put("message", "Blocked by Sentinel (flow limiting)");
        }
        //打印异常
        e.printStackTrace();
        //将map对象转换为json格式字符串
        String jsonStr=new ObjectMapper().writeValueAsString(map);
        pw.println(jsonStr);
        pw.flush();
    }
}

小结

降级的策略有哪些(慢调用,异常比例,异常数)

熔断处理逻辑中的有哪些状态?(Open,HalfOpen,Closed)

熔断之后出于什么状态(熔断打开状态Open,在次访问情况依旧,会继续熔断)

熔断时长到期后处于什么部分(探测-HalfOpen)

熔断恢复正常之后,会处于什么状态?(熔断关闭-closed)

何为熔断?(让外部应用停止对服务的访问,生活中跳闸,此路不通)

为什么要熔断?(让服务器休息一下,外部应用停止对服务的访问。平均响应速度越来越慢或经常出现异常,这样可能会导致调用链堆积,最终系统崩溃)

Sentinel中限流,降级的异常什么,父类是谁?(DegradeException,BlockException)

sentinel出现异常时处理的接口是谁?(BlockExceptionHandler)

Sentinel中处理接口下默认的现实类是(DefaultBlockExceptionHandler)

加入Sentinel默认的异常处理规则不满足我们的需求怎么办(自定义)

如何自定义Sentinel的异常处理规则呢(直接或间接实现BlockExceptionHandler)

热点

热点就是经常访问的数据

设置某个数据为热点数据,对这个数据的访问进行限流

第一步:使用@SentinelResoutc(“命名限流节点”)创建一个节点

     //http://ip:port/consumer/doFindById?id=10
        @GetMapping("/consumer/findById")
        @SentinelResource("res")
        public String doFindById(@RequestParam("id") Integer id){
            return "resource id is "+id;
        }

第二步:服务启动后,选择要限流的热点链路,如图所示:在这里插入图片描述

 第三步:设置要限流的热点,如图所示:

热点限流只有QPS模式。参数索引表示网页URL?后面携带的参数,第一个参数的索引就是0,第二个是1....

单机阈值和统计时长表示此窗口在规定时间内访问的数量超过阈值,就进行限流

在这里插入图片描述

 第四步:多次访问热点参数方法,前端会出现如下界面,如图所示:

在这里插入图片描述

 此时后台通报的异常信息

com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException: 2

特定参数设计

配置参数例外项,如图所示:在这里插入图片描述

对参数值为5时阈值为100,其它参数值阈值为1,例如当我们访问http://ip:port/consumer/doRestEcho1?id=5时的限流阈值为100。

小结面试分析

如何理解热点数据————访问频率较高的数据,热销商品,流行元素

热点限流规则是怎样的?————主要是针对参数进行限流设计

热点数据的特殊参数如何理解————针对某个特定值的特殊限流规则

对于热点数据的访问出现限流以后的底层异常是什么?————ParamFlowException

Sentinel系统规则在这里插入图片描述

 Load(仅对Linux生效):当load1超过阈值,且当前系统的并发现场数炒货系统容量时候才会触发系统包会,系统容量由系统的maxQps*minRt计算得出,参考值一般是CPU cores*2.5

cpu使用率:当cpu使用频率超过阈值触发保护

RT:当机器上所有入口流量的并发线程达到阈值即触发保护,单位是毫秒

线程数:机器上的线程数到达上限触发保护

入口QPS:当流量的QPS达到阈值触发系统保护

如何理解sentinel中的系统规则?(是对所有链路的一种规则控制,是一种系统保护策略)

Sentinel的常用规则有哪些?(RT,QPS,CPU,线程,Load-linux,unix)

Sentinel系统保护规则被处罚之后底层会抛出什么异常(SystemBlockException)

Sentinel授权规则

在这里插入图片描述

 资源名:限流的作用对象

控流应用:对应的黑白名单设置的规则值,多个,隔开

授权类型:白名单(放行),黑名单(不允许访问)

第一步,定义请求解析器,队请求进行解析,判断是否符合要求

@Component
public class DefaultRequestOriginParser  implements RequestOriginParser  {
    /**
     * 定义一个请求源解析对象,并基于此对象对请求中制定数据进行解析
     *然后Sentinel底层会对此接口方法的返回值基于规则定义进行解析处理
     */
    //解析请求源数据
    @Override
    public String parseOrigin(HttpServletRequest request) {
        //请求参数进行限制
        //获取请求参数数据,名字可以自己写
        //http://ip:port/path?orgin=app1
        //return request.getParameter("origin");

        //对ip进行限制
        String ip = request.getRemoteAddr();
        System.out.println(ip);
        return ip;
    }//授权规则中的黑白名单的值,来自此方法的返回值
}

第二步:定义流控规则,如图所示:在这里插入图片描述

第三步:执行资源访问,检测授权规则应用在这里插入图片描述

 设计过程分析

在这里插入图片描述

小结

如何理解Sentinel中的授权规则?        对制定资源访问给出的一种简易的授权策略

Sentinel的授权规则是如何设计的?                黑(不可访问)/白(允许访问)名单

如何识别黑白名单?            在拦截器中通过调用RequestOriginParser对象的方法检测具体的规则

授权规则中RequesOriginParser类的作用是什么?

对控流应用值进行解析,检查服务访问时的传入值是否与RequestOriginParser的ParserOrigin是否一致

重点

Sentinel诞生的背景?        计算机的处理是有限的,但是并发的量是不确定的

服务中心Sentinel环境的集成,初始化?        添加依赖,sentinel配置

sentinel限流规则(阈值类型:QPS,线程数。 限流模式:关联,直接,链路)

sentinel降级,熔断的策略?        慢调用。比例异常,异常数

sentinel热点规则设计?        针对数据进行控制

Sentinel系统规则设计?        掌握全局规则定义,针对所有请求有效

sentine授权规则设计?        黑白名单

FAQ分析

为什么要限流?        服务器的处理能力是有限的,并发的量是不确定的

你了解的限流框架: Sentinel

常见的限流算法: 令牌桶,漏斗,滑动,计数

sentinel限流规则: qps,线程数

sentinel限流模式:直接,关联,链路

sentinell的降级和熔断的策略有哪些:慢调用,响应时间长,异常比例,异常占比,异常数

sentinel的热点规则中的热点数据:        流行元素,热点信息

sentinel的黑白名单:黑(不可访问,拦截)白(放行通过)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值