【接口限流】简单计数器Python实现固定窗口限流

限流的目的

保证系统可用的一个重要手段,和消息队列相似,都是防止超负荷的流量直接打在服务上造成故障,但又有所不同,消息队列其中一个作用是削峰,但是带来的副作用是异步,业务流程需要配合,而限流则是对请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理。

有几种常见的限流手段

  • 固定时间窗口限流
  • 滑动时间窗口限流
  • 漏桶限流
  • 令牌桶限流

固定窗口限流

本文主要说明固定窗口限流,首先需要先理解一个概念:时间窗口。简单来说就是把时间分成一个个小格子,而固定窗口限流的作用就是限制单位串口内的请求数,防止系统超载。如下图,相同颜色的格子组成1s,假设单位时间(1s)内限流数是100,那么下图的结构是初步满足需求的。

分析问题主要的要素有:当前时间窗口内累计请求数、单位时间窗口允许的最大请求数、单位时间大小。

主要的操作有:

        判断是否限流:判断单位时间内累计请求数是否大于最大请求数。

        更新时间窗口:每单位时间移动一个时间窗口。

class CountLimit(FlowLimit):

    def __init__(self, func):
        super(CountLimit, self).__init__(func)
        self.reqCounter = 0                           # 当前窗口流量
        self.limitNum = 100                           # 限流次数
        self.interval = 1000                          # 限流时间间隔(ms)
        self.currentTime = self.getNow()              # 当前时间

    def __call__(self, request, *args, **kwargs):
        if self.isLimit():
            raise Exception("flow limit")

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

    def isLimit(self) -> bool:
        """
        判断是否限流
        :return:
        """
        self.__roll_window()
        if (self.reqCounter+1 > self.limitNum):
            print("flow limit")
            return True

        self.reqCounter += 1
        return False
    
    def __roll_window(self):
        """
        更新到最新时间窗口
        :return: 
        """
        now = self.getNow()
        if (now > self.interval+self.currentTime):
            self.reqCounter = 0
            self.currentTime = now

缺点

固定时间窗口实现起来简单,但是缺陷是误差太大,如下图,第二和第三个0.5s组成的1s明显超过限流数了。滑动时间窗口限流算法可以缓解这一问题。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值