zoukankan      html  css  js  c++  java
  • Sentinel 流控效果

    https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

    直接拒绝

    直接拒绝(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。具体的例子参见 FlowQpsDemo

    Warm Up  (针对激增流量)

    https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8

    Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。详细文档可以参考 流量控制 - Warm Up 文档,具体的例子可以参见 WarmUpFlowDemo

    通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:

    image

    当流量突然增大的时候,我们常常会希望系统从空闲状态到繁忙状态的切换的时间长一些。即如果系统在此之前长期处于空闲的状态,我们希望处理请求的数量是缓步的增多,经过预期的时间以后,到达系统处理请求个数的最大值。Warm Up(冷启动,预热)模式就是为了实现这个目的的。

    这个场景主要用于启动需要额外开销的场景,例如建立数据库连接等。

    它的实现是在 Guava 的算法的基础上实现的。然而,和 Guava 的场景不同,Guava 的场景主要用于调节请求的间隔,即 Leaky Bucket,而 Sentinel 则主要用于控制每秒的 QPS,即我们满足每秒通过的 QPS 即可,我们不需要关注每个请求的间隔,换言之,我们更像一个 Token Bucket

    我们用桶里剩余的令牌来量化系统的使用率。假设系统每秒的处理能力为 b,系统每处理一个请求,就从桶中取走一个令牌;每秒这个令牌桶会自动掉落b个令牌。令牌桶越满,则说明系统的利用率越低;当令牌桶里的令牌高于某个阈值之后,我们称之为令牌桶"饱和"。

    当令牌桶饱和的时候,基于 Guava 的计算上,我们可以推出下面两个公式:

    rate(c)=m*c+ coldrate
    

    其中,rate 为当前请求和上一个请求的间隔时间,而 rate 是和令牌桶中的高于阈值的令牌数量成线形关系的。cold rate 则为当桶满的时候,请求和请求的最大间隔。通常是 coldFactor * rate(stable)

    通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:

    冷启动过程 QPS 曲线

    默认 coldFactor 为 3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。

    application.yml

    server:
      port: 8052
      #应用名称  (sentinel 会将该名称当作服务名称)
    spring:
      application:
        name: order-sentinel
      cloud:
        sentinel:
          transport:
            dashboard: 127.0.0.1:8858
          web-context-unify: false #默认将调用链路收敛
    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.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流控了";
        }
    
    }

    匀速排队  (针对脉冲流量)

    匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。详细文档可以参考 流量控制 - 匀速器模式,具体的例子可以参见 PaceFlowDemo

    该方式的作用如下图所示:

    image

    这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。

    注意:匀速排队模式暂时不支持 QPS > 1000 的场景。

  • 相关阅读:
    年纪大了,要学会控制自己的欲望
    java为什么要用类型擦除实现泛型?--c++,java,c# 的泛型是如何实现的
    面向对象:类的成员---只是特定(类的)命名空间的全局变量(函数)而已
    人的意志与自然法则—人的意志与人造事物
    所有的思考都有两个目的:建模降熵
    控制论、系统论与熵
    秩序(也常简称为序)是系统的本质特征之一
    控制论:基于全局信息和整体目标、整体规则的系统结构和状态维护
    人类社会的全部认识成果可以概括为三大领域的科学,即自然科学、社会科学和思维科学
    “逻辑”的古希腊词源
  • 原文地址:https://www.cnblogs.com/mingforyou/p/15643842.html
Copyright © 2011-2022 走看看