美文网首页
漏水桶和令牌桶的限流算法

漏水桶和令牌桶的限流算法

作者: xyt001 | 来源:发表于2019-07-15 23:31 被阅读0次

    前言:

    服务上线后,我们一般会对自己 服务 有个 预估,这个 服务能够 承受多少请求,当单位时间内请求数过高超过我们 预估 的 阀值,我们就应该 拒绝多余的请求。我们 一般会用 漏水桶 和令牌桶算法来实现 以上逻辑。

    令牌桶算法:

    原理:

    一个水桶按照一定速率往桶里放令牌,每一个请求进来 都会去水桶里面尝试 获取 令牌,如果 没有获取到 就 拒绝 该请求。水桶有一定的容量,最多只能放 n个 令牌,当令牌 数量过多就会 溢出。

    代码实现:

    var (
        lastReqTime        = time.Now().Unix() //上个请求 的时间戳
        lastTokenNum int64 = 1                 //上次请求时剩余的令牌
        tokenRate    int64 = 1                 //每秒增加 1 个 token
        bucketCap    int64 = 100               //令牌桶的总量
    
    )
    
    func tokenLimiter() bool {
        nowT := time.Now().Unix() //当前时间
        //(当前时间 减去 上次请求时间 ) 乘 速度 = 这段时间 生产的 令牌数 加上 原来的 令牌数  判断 令牌 数是否 大于 桶的 容量 ,如果 大于 就取桶容量
        nowTokenNum := int64(math.Min(float64((nowT-lastReqTime)*tokenRate+lastTokenNum), float64(bucketCap))) //现在令牌还有的数量
    
        if nowTokenNum > 0 {
            lastReqTime = nowT
            lastTokenNum--
            return true
        }
    
        return false
    }
    

    漏水桶算法:

    原理:

    一个水桶下面有个洞,会按照一定的速度漏水,每次一个请求过来 就相当于 往水桶里面加一滴水 ,如果 当前 水桶 满了 ,请求 就会溢出,溢出的水就相当于 是 被拒绝的请求。

    代码实现:

    var (
        lastReqTime       = time.Now().Unix() //上次请求时间
        lastReqNum  int64 = 10                //上次水桶剩余的数量
        leakyRate   int64 = 1                 //漏水速度每秒漏一滴
        bucketCap   int64 = 100               //令牌桶的总容量
    )
    
    func leakyLimiter() bool {
        nowT := time.Now().Unix() //当前时间
        //当前水量 = (上次剩余的水量 - 这段时间流去的水量) , 当前水量 最小为 0
        nowReqNum := int64(math.Max(float64(lastReqNum-(nowT-lastReqTime)*leakyRate), 0))
    
        //如果当前 水量已经比桶的大了 ,就直接返回 false 说明 水溢出了
        if nowReqNum > bucketCap {
            return false
        }
    
        lastReqNum++
        lastReqTime = nowT
    
        return true
    }
    

    总结:

    1. 多方资料都说令牌桶 要比 漏水桶 好,因为 令牌桶 在 限流的同时还允许 在短时间内的 合理并发(我个人觉得其实差不多, 漏水桶 从空桶 激增到 溢出 不也并发么)
    2. 这个代码只是学习,线上生产还应该考虑到原子操作等.
    3. 可以 用redis 配合 lua 来做这块逻辑

    相关文章

      网友评论

          本文标题:漏水桶和令牌桶的限流算法

          本文链接:https://www.haomeiwen.com/subject/clnikctx.html