限流算法
为什么需要限流?
计数器算法 (Fixed Window Counter)
- window_start_time
- counter
- limit = rate * window_size
- window_size
初始化: - counter=1
- window_start_time = 初始时间戳
请求到来 - 根据请求到来的时间戳判断是否超过当前时间窗口
- 超过:window_start_time=当前请求时间戳
- 未超过:counter>limit
- 大于:拒绝请求
- 小于等于:counter++ 允许请求
滑动窗口算法
基于日志(Sliding Window Log)
- window_start_time
counters[]
- limit = rate * window_size
- window_size
初始化 - 维护一个有序列表(队列最佳),记录请求带来的时间戳序列
请求到来 - 清除now_time-window_size之前的请求记录
- 当前列表数量<limit?
- limit = rate * window_size
- window_size = sub_window_count * sub_window_size
- sub_window_count
counters[sub_window_count]
哈希表
初始化:- counters中计数器为0
请求到来 - 计算窗口起始位置 window_start_time = now-window_size
- 清理起始位置之前窗口(定时),通过清理sub_window_size * key< window_start_time的元素
- 计算当前窗口总数: total_count = 累加counters 中的值,key值应该在(window_start_time之后)
- 判断是否超限:total_count>=limit?
- 上次请求时间戳 last_time
- 桶容量
- 上次桶水量 lastwater
- 速率 rate
请求到来 - 获取漏水量=(now-last_time) * rate
- 获得桶水量 = current_water-漏水量
- 判断当前桶是否满
- 上次令牌数量 last_token
- 最大token数量 max_token
- 速率 rate
- 上次请求时间 last_time
请求到来: - 计算添加令牌 add = rate * (now-last_time)
- 计算当前令牌 = min(last_token+add,max_token)
- 判断是否存在令牌 当前令牌>0
- 存在:当前令牌— 允许请求
- 不存在:拒绝请求
评论