延迟限流算法

目录

设计原因

设计背景

现有限流算法不适用 

设计思路

图解

缺点

实现方式

实现思路

限流算法的优化

窗口坐标的计算

过期时间-redis实现

lua脚本管理限流key

延迟请求实现

延迟队列

重启丢失问题解决

实现方案优化

注解设计

自定义延迟任务处理和拒绝策略自定义实现需要实现接口

切面实现

使用范围

增强方式

SpEL解析

Spring Boot Starters

使用

普通限流延迟

自定义延迟任务、自定义限流后补充执行任务


设计原因

设计背景

有一个业务需求,是需要获取部门成员总数展示。

当时想到了两种方案:

        一是定时计算每个部门的数据再进行更新。

        二是监听成员表,部门成员数据每次出现变更的时候对部门数据进行计算更新。

        对于一来说,部门组织架构不是一个会非常平凡变更的数据,因此每次全表计算会造成一些性能损耗。所以,选择方案二。

        方案二存在的问题:比如在导入组织架构的时候,一个部门数据频繁变更,部门数据大量重复计算更新,可能导致系统雪崩。

        因此,需要控制同一部门数据频繁请求,达到一段时间同一部门更新限量次数的目的。

现有限流算法不适用

        行业使用的限流算法会把超过限制的请求过滤掉,以至于丢失掉之后的更新,这种只适合幂等更新的限制,不适用于汇总计算更新。

设计思路

        理想设计是,如果能够知道这段时间对于这个部门最后一次变更的时间,再在这个时间后调用接口更新计算部门总数。

        但是目前没有想到一个好的办法知道这个请求是不是最后一个请求。

        所以使用一个折中的思路,对限流算法进行优化,我们预设某一个请求是最后一个请求,并进行执行。

        怎么预设呢。

        如果该时间段限流了,就添加一个执行任务到下一个限流时间段,预设被放到下一个时间段的请求是最后一个请求。这样就能保证上一个时间段的数据一定是最新的,但是会存在一个时间窗口的数据延迟。eg:12:00:10有请求超过了一分钟的限制次数,就把这个请求延迟到12:01:10执行)

图解

限流次数:n

时间窗口: t秒

        单位时间t1内请求限流n次,大于n次之后,将第n+1请求延迟到下一个时间窗口t2发送,剩余请求丢弃。

缺点

上面也提到了,延迟限制后的更新会在下一个时间窗口执行,所以会有一个时间窗口的误差。

实现方式

        固定窗口 + 延迟请求

实现思路

限流算法的优化

        常用的4种限流算法有:固定窗口算法、滑动窗口算法(每次都以当前时间为开始,往后t的长度为窗口)、漏桶算法(请求加一,消费减一,当count>limit开始限制)、令牌桶算法(系统每恒定的时间往令牌通放令牌.如果令牌被用完了,就限制)。 

        4种算法中固定窗口算法实现最为简单,并且已经满足了我们单位时间内限制的需要,所以选择用固定窗口算法。

       如果想要更准确限流,也可以改用滑动窗口。但是实现就更复杂了,感觉也没那么必要。

窗口坐标的计算

默认坐标的简单实现,用当前时间的秒数/窗口大小

这只是一种简单的实现,为了防止坐标的碰撞,用这种算法的话需要窗口大小需要时60的因子

       如果有特殊需要,也可以实现WindowPointSecond接口,自定义时间窗口算法。

        

/**
 * 限流窗口坐标计算接口
 */
public interface WindowPointService {

    /**
     * 区间坐标
     * @return
     */
    Integer getPoint();

    /**
     * 区间时间(单位:s)
     * @return
     */
    Integer getSectionTime();

}
Footer

时间坐标枚举06fa67132827aa417b08d32152cece6d.png

定时窗口实现

过期时间-red

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值