限流算法--计数器算法
kevinyan815 opened this issue · 0 comments
kevinyan815 commented
算法**
计数器是一种比较简单粗暴的限流算法,其**是在固定时间窗口内对请求进行计数,与阀值进行比较判断是否需要限流,一旦到了时间临界点,将计数器清零。
面临的问题
计数器算法存在“时间临界点”缺陷。比如每一分钟限制100个请求,可以在00:00:00-00:00:58秒里面都没有请求,在00:00:59瞬间发送100个请求,这个对于计数器算法来是允许的,然后在00:01:00再次发送100个请求,意味着在短短1s内发送了200个请求,如果量更大呢,系统可能会承受不住瞬间流量,导致系统崩溃。(如下图所示)
所以计数器算法实现限流的问题是没有办法应对突发流量。
Go代码实现
type LimitRate struct {
rate int //阀值
begin time.Time //计数开始时间
cycle time.Duration //计数周期
count int //收到的请求数
lock sync.Mutex //锁
}
func (limit *LimitRate) Allow() bool {
limit.lock.Lock()
defer limit.lock.Unlock()
// 判断收到请求数是否达到阀值
if limit.count == limit.rate-1 {
now := time.Now()
// 达到阀值后,判断是否是请求周期内
if now.Sub(limit.begin) >= limit.cycle {
limit.Reset(now)
return true
}
return false
} else {
limit.count++
return true
}
}
func (limit *LimitRate) Set(rate int, cycle time.Duration) {
limit.rate = rate
limit.begin = time.Now()
limit.cycle = cycle
limit.count = 0
}
func (limit *LimitRate) Reset(begin time.Time) {
limit.begin = begin
limit.count = 0
}