Sentinel 热点参数限流

https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81

 

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

Sentinel Parameter Flow Control

Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。

热点参数规则

热点参数规则(ParamFlowRule)类似于流量控制规则(FlowRule):

 

 

属性说明默认值
resource 资源名,必填  
count 限流阈值,必填  
grade 限流模式 QPS 模式
durationInSec 统计窗口时间长度(单位为秒),1.6.0 版本开始支持 1s
controlBehavior 流控效果(支持快速失败和匀速排队模式),1.6.0 版本开始支持 快速失败
maxQueueingTimeMs 最大排队等待时长(仅在匀速排队模式生效),1.6.0 版本开始支持 0ms
paramIdx 热点参数的索引,必填,对应 SphU.entry(xxx, args) 中的参数索引位置  
paramFlowItemList 参数例外项,可以针对指定的参数值单独设置限流阈值,不受前面 count 阈值的限制。仅支持基本类型和字符串类型  
clusterMode 是否是集群参数流控规则 false
clusterConfig 集群流控相关配置

 

 

package com.wsm.order.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.wsm.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    OrderService orderService;

    @RequestMapping("/add")
    public String add(){
        System.out.println("下单成功!");
        return "生成订单";
    }

    @RequestMapping("/get")
    public String get(){
        System.out.println("查询订单!");
        return "查询订单";
    }

    @RequestMapping("/test1")
    public String test1(){
        return orderService.getUser();
    }

    @RequestMapping("/test2")
    public String test2(){
        return orderService.getUser();
    }

    @RequestMapping("/flow")
//    @SentinelResource(value = "flow",blockHandler = "flowBlockHandler")
    public String flow(){
        System.out.println("========flow====");
        return "正常访问";
    }

    public String flowBlockHandler(BlockException e){
        return "流控了";
    }

    @RequestMapping("/flowThread")
//    @SentinelResource(value = "flowThread",blockHandler = "flowThreadBlockHandler")
    public String flowThread() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("flowThread正常访问");
        return "正常访问";
    }

    public String flowThreadBlockHandler(BlockException e){
        return "flowThread流控了";
    }

    @RequestMapping("/err")
    public String err() {
        int a=1/0;
        return "err";
    }

    @RequestMapping("/get/{id}")
    @SentinelResource(value = "getById", blockHandler = "HotBlockHandler")
    public String getById(@PathVariable("id") Integer id) {
        System.out.println("正常访问:"+id);
        return "正常访问:"+id;
    }

    public String HotBlockHandler(@PathVariable("id") Integer id,BlockException e) {
        return "热点异常处理"+id;
    }

}

 

 

 

 

 

 

 

 

单机阈值:

1、假设 参数大部分值都是热点参数,那单机阈值就主要针对热点参数进行流控。后续再额外针对普通的参数进行流控。

2、假设 参数大部分值都是普通流量,那单机阈值就主要针对普通参数进行流控。

 

统计窗口时长 )内 的QPS (单机阈值

 

系统吞吐量几个重要参数:QPS(TPS)、并发数、响应时间

     QPS(Query Per Second),QPS 其实是衡量吞吐量(Throughput)的一个常用指标,就是说服务器在一秒的时间内处理了多少个请求 —— 我们通常是指 HTTP 请求,显然数字越大代表服务器的负荷越高、处理能力越强。作为参考,一个有着简单业务逻辑(包括数据库访问)的程序在单核心运行时可以提供 50 - 100 左右的 QPS,即每秒可以处理 50 - 100 个请求。
   TPS(Transaction Per Second) 每秒钟系统能够处理的事务的数量。

        QPS(TPS):每秒钟 request/事务 的数量  (此处 / 表示 或的意思)

        并发数: 系统同时处理的request/事务数  (此处 / 表示 或的意思)

        响应时间:  一般取平均响应时间

理解了上面三个要素的意义之后,就能推算出它们之间的关系:

QPS(TPS)= 并发数/平均响应时间

        一个系统吞吐量通常由QPS(TPS)、并发数两个因素决定,每套系统这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降,原因是系统超负荷工作,上下文切换、内存等等其它消耗导致系统性能下降。

     并发用户数和QPS两个概念没有直接关系,但是如果要说QPS时,一定需要指明是多少并发用户数下的QPS,否则毫无意义,因为单用户数的400QPS和200并发用户数下的400QPS是两个不同的概念。前者说明该应用可以在一秒内串行执行400个请求,而后者说明在并发200个请求的情况下,一秒内该应用能处理400个请求,当QPS相同时,越大的并发用户数,代表了网站并发处理能力越好。对于当前的web服务器,其处理单个用户的请求肯定戳戳有余,这个时候会存在资源浪费的情况(一方面该服务器可能有多个cpu,但是只处理单个进程,另一方面,在处理一个进程中,有些阶段可能是IO阶段,这个时候会造成CPU等待,但是有没有其他请求进程可以被处理)。而当并发数设置的过大时,每秒钟都会有很多请求需要处理,会造成进程(线程)频繁切换,反正真正用于处理请求的时间变少,每秒能够处理的请求数反而变少,同时用户的请求等待时间也会变大,甚至超过用户的心理底线。所以在最小并发数和最大并发数之间,一定有一个最合适的并发数值,在该并发数下,QPS能够达到最大。但是,这个并发并非是一个最佳的并发,因为当QPS到达最大时的并发,可能已经造成用户的等待时间变得超过了其最优值,所以对于一个系统,其最佳的并发数,一定需要结合QPS,用户的等待时间来综合确定。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2021-12-10 20:48  残星  阅读(524)  评论(0编辑  收藏  举报