【接口限流】Python实现滑动时间窗口限流

滑动时间窗口

滑动时间窗口,又称rolling window。为了解决计数器法统计精度太低的问题,引入了滑动窗口算法。比如下图,第二个和第三个组成的时间窗口明显不满足限流要求(单位时间内100个请求数)。

 时间窗口拆分为更小粒度,再来看看,前1s仍然满足限流要求

窗口往后滑动一个小格子(0.1s)后 ,触发限流,由此看出,滑动时间窗口可以很大程度的避免计数器统计法带来的精度问题。

 代码实现:

class RollintWindowLimit(FlowLimit):

    def __init__(self, func):
        super(RollintWindowLimit, self).__init__(func)
        self.threshold = []                                         # 滑动窗口
        self.limitNum = 10                                          # 限流次数                                
        self.interval = 1000                                        # 间隔时间 ms
        self.maxRoll = 10                                           # 滑动小窗口数  
        self.sleepTime = (self.interval // self.maxRoll) / 1000     # 窗口滑动频率
        self.reqCount = 0                                           # 滑动窗口内请求计数器
        self.__init_threshold()
        
    def __call__(self, request, *args, **kwargs):

        if self.isLimit():
            print("限流中")
            return HttpResponse("Error: Flow limit")

        ret = self.func(request, self.reqCount, *args, **kwargs)
        return ret

    def __init_threshold(self):

        def roll_window():
            """
            小时间窗口,一直往后滑动
            :return:
            """
            # 插入一个元素
            while True:
                self.threshold.append(0)
                # 判断是否满了,如果满了需要把头去掉
                if len(self.threshold) > self.maxRoll:
                    count = self.threshold.pop(0)
                    self.reqCount -= count  # 更新当前流量情况

                time.sleep(self.sleepTime)
                
        t = threading.Thread(target=roll_window, daemon=False)
        t.start()
        
    def isLimit(self) -> bool:

        if self.reqCount+1 > self.limitNum:
            return True

        self.reqCount += 1   # 当前访问总数+1
        self.threshold[-1] =  self.threshold[-1] + 1  # 最近一个时间窗口请求数+1
        return False

缺点

滑动时间窗口也不是绝对精准的,这取决于拆分的精度,窗口拆分得越精细,窗口也就越平滑,限流得统计也越精确,但是造成的计算量也越大。具体情况具体分析。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值