首次提交:姜十三论坛
后端 Go+Gin:认证/CSRF/限流、板块、帖子、评论、点赞、通知、用户资料、置顶推荐;前端 Next.js 16:发帖/编辑/删除、搜索、分页、点赞、通知中心、设置;基础设施 docker-compose 与配置模板;添加 .gitignore 与专有许可证(保留所有权利)
This commit is contained in:
79
backend/service/ratelimit.go
Normal file
79
backend/service/ratelimit.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RateLimiter 内存速率限制器
|
||||
type RateLimiter struct {
|
||||
mu sync.Mutex
|
||||
records map[string][]time.Time
|
||||
limits map[string]int // key -> 每分钟最大请求数
|
||||
cooldown map[string]time.Duration
|
||||
}
|
||||
|
||||
func NewRateLimiter() *RateLimiter {
|
||||
return &RateLimiter{
|
||||
records: make(map[string][]time.Time),
|
||||
limits: make(map[string]int),
|
||||
cooldown: make(map[string]time.Duration),
|
||||
}
|
||||
}
|
||||
|
||||
// SetLimit 设置某类请求的每分钟限制
|
||||
func (r *RateLimiter) SetLimit(key string, perMinute int) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.limits[key] = perMinute
|
||||
}
|
||||
|
||||
// Allow 检查是否允许请求
|
||||
func (r *RateLimiter) Allow(key string) bool {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
limit, ok := r.limits[key]
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
windowStart := now.Add(-1 * time.Minute)
|
||||
|
||||
// 清理过期记录
|
||||
records := r.records[key]
|
||||
valid := records[:0]
|
||||
for _, t := range records {
|
||||
if t.After(windowStart) {
|
||||
valid = append(valid, t)
|
||||
}
|
||||
}
|
||||
|
||||
if len(valid) >= limit {
|
||||
r.records[key] = valid
|
||||
return false
|
||||
}
|
||||
|
||||
valid = append(valid, now)
|
||||
r.records[key] = valid
|
||||
return true
|
||||
}
|
||||
|
||||
// 速率限制类型常量
|
||||
const (
|
||||
RateLogin = "login"
|
||||
RateRegister = "register"
|
||||
RatePost = "post"
|
||||
RateComment = "comment"
|
||||
)
|
||||
|
||||
// DefaultRateLimiter 创建默认速率限制器
|
||||
func DefaultRateLimiter() *RateLimiter {
|
||||
rl := NewRateLimiter()
|
||||
rl.SetLimit(RateLogin, 20) // 登录 20/分钟
|
||||
rl.SetLimit(RateRegister, 10) // 注册 10/分钟
|
||||
rl.SetLimit(RatePost, 10) // 发帖 10/分钟
|
||||
rl.SetLimit(RateComment, 30) // 评论 30/分钟
|
||||
return rl
|
||||
}
|
||||
Reference in New Issue
Block a user