添加 security/ratelimit.go
This commit is contained in:
72
security/ratelimit.go
Normal file
72
security/ratelimit.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// security/ratelimit.go
|
||||||
|
package security
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequestCounter struct {
|
||||||
|
Count int
|
||||||
|
ResetTime time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type RateLimiter struct {
|
||||||
|
requests sync.Map
|
||||||
|
limit int
|
||||||
|
window time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRateLimiter(limit int, window time.Duration) *RateLimiter {
|
||||||
|
rl := &RateLimiter{
|
||||||
|
limit: limit,
|
||||||
|
window: window,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动清理协程
|
||||||
|
go rl.cleanup()
|
||||||
|
|
||||||
|
return rl
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rl *RateLimiter) Allow(sessionID string) bool {
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
val, _ := rl.requests.LoadOrStore(sessionID, &RequestCounter{
|
||||||
|
Count: 0,
|
||||||
|
ResetTime: now.Add(rl.window),
|
||||||
|
})
|
||||||
|
|
||||||
|
counter := val.(*RequestCounter)
|
||||||
|
|
||||||
|
// 检查是否需要重置
|
||||||
|
if now.After(counter.ResetTime) {
|
||||||
|
counter.Count = 1
|
||||||
|
counter.ResetTime = now.Add(rl.window)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否超过限制
|
||||||
|
if counter.Count >= rl.limit {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
counter.Count++
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rl *RateLimiter) cleanup() {
|
||||||
|
ticker := time.NewTicker(5 * time.Minute)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for range ticker.C {
|
||||||
|
now := time.Now()
|
||||||
|
rl.requests.Range(func(key, value interface{}) bool {
|
||||||
|
counter := value.(*RequestCounter)
|
||||||
|
if now.After(counter.ResetTime.Add(5 * time.Minute)) {
|
||||||
|
rl.requests.Delete(key)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user