-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfixed_window_rate_limiter.go
More file actions
50 lines (43 loc) · 1.11 KB
/
fixed_window_rate_limiter.go
File metadata and controls
50 lines (43 loc) · 1.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package ratelimiter
import (
"sync"
"time"
)
type FixedWindowRateLimiter struct {
threshold int `json:"threshold"` // 阈值
stime time.Time `json:"stime"` // 开始时间
interval time.Duration `json:"interval"` // 时间窗口
counter int `json:"counter"` // 当前计数
lock sync.Mutex
}
func NewFixedWindowRateLimiter(threshold int, interval time.Duration) *FixedWindowRateLimiter {
return &FixedWindowRateLimiter{
threshold: threshold,
stime: time.Now(),
interval: interval,
counter: threshold - 1, // 让其处于下一个时间窗口开始的时间临界点
}
}
func (l *FixedWindowRateLimiter) Allow() bool {
l.lock.Lock()
defer l.lock.Unlock()
// 判断收到请求数是否达到阈值
if l.counter == l.threshold-1 {
now := time.Now()
// 达到阈值后,判断是否是请求窗口内
if now.Sub(l.stime) >= l.interval {
// 重新计数
l.Reset()
return true
}
// 丢弃多余的请求
return false
} else {
l.counter++
return true
}
}
func (l *FixedWindowRateLimiter) Reset() {
l.counter = 0
l.stime = time.Now()
}