zoukankan      html  css  js  c++  java
  • 限流

      在高并发中,有三把利器来保护系统:缓存、降级和限流。那么何为限流,就是限制流量,对系统的出入流量进行控制,防止大流量出入,导致资源不足,系统不稳定。

      常见的三种限流算法:计数器算法,滑动窗口,令牌桶算法

    1.计数器算法

      比如规定,对于A接口来说,我们一分钟的访问次数不能超过100次。那么我们可以这么做,在一开始的时候,我们可以设置一个计数器,每当一个请求过来的时候,计数器加一,如果计数器值大于100且并且该请求与第一次请求的间隔还在一分钟之内。那么说明请求过多;如果该请求与第一个请求的间隔大于1分钟,且计数器值还在限流器范围内。那么就重置计数器。

    public class CounterTest {
        public long timeStamp = getNowTime();
        public int reqCount = 0;
        public final int limit = 100; // 时间窗口内最大请求数
        public final long interval = 1000; // 时间窗口ms
    
        public boolean grant() {
            long now = getNowTime();
            if (now < timeStamp + interval) {
                // 在时间窗口内
                reqCount++;
                // 判断当前时间窗口内是否超过最大请求控制数
                return reqCount <= limit;
            } else {
                timeStamp = now;
                // 超时后重置
                reqCount = 1;
                return true;
            }
        }
    
        public long getNowTime() {
            return System.currentTimeMillis();
        }
    }
    

      优点:能够实现控制并发数的效果

      缺点:使用场景单一,适用单机,一般用来对入流量进行控制

    2.滑动窗口

      roling windows

     上图中,整个红色的矩形表示一个时间窗口,在我们的例子中,一个时间窗口就是一个分钟,然后我们将时间窗口进行划分,比如途中,我们就将滑动窗口化成6格,所以每格代表10秒钟。每过10秒钟,我们的时间窗口就会往右滑动一格。每一个格子都有自己对应独立的计数器,比如当一个请求在0:35秒的时候到达,那么0:30~0:39对应的计数器就会加1

      当0:59到达100格请求会落在灰色格子里,而1:00到达的请求会落在橘黄色的格子中。当时间到达1:00时,我们的窗口会往右移动一格,那么此时时间窗口内的总请求数量一共是200个,超过了限定的100个,所以此时能够检测出来触发了限流。

    --- 资源唯一标识
    local key = KEYS[1]
    --- 时间窗最大并发数
    local max_window_concurrency = tonumber(ARGV[1])  
    --- 时间窗
    local window = tonumber(ARGV[2])  
    --- 时间窗内当前并发数
    local curr_window_concurrency = tonumber(redis.call('get', key) or 0)  
    if current + 1 > limit then
        return false
    else
        redis.call("INCRBY", key,1)    
        if window > -1 then
            redis.call("expire", key,window)    
        end
        return true
    end
    

      优点: 通过时间窗最大请求数可以直接换算出最大的QPS(QPS = 请求数/时间窗)

      缺点: 可能出现流量不平滑,时间窗内一小段流量占比特别大。

    3.令牌桶

      1)所有请求在处理之前都需要拿到一个可用的令牌才会被处理

      2)根据限流大小,设置按照一定速率往桶里添加令牌

      3)桶设置最大的放置令牌限制,当桶满时,新添加的令牌就被丢弃或者拒绝

      4)请求到达后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理业务逻辑后,将令牌直接删除

      5) 令牌桶右最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流

    博客来源:

      https://www.cnblogs.com/linjiqin/p/9707713.html

      https://mp.weixin.qq.com/s/3KF7Rcy5y3_RNFQZe4HX5Q

  • 相关阅读:
    [leetcode]5最长回文子串
    [leetcode]4寻找两个有序数组的中位数
    [leetcode]3无重复字符的最长字串
    [leetcode]2两数相加
    [leetcode]1两数之和
    [学习记录]堆
    [学习记录]平衡树
    [学习记录]二叉树删除
    [学习记录]排序算法总结
    创建mysql数据库
  • 原文地址:https://www.cnblogs.com/huan30/p/12079783.html
Copyright © 2011-2022 走看看