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" RateChat = "chat" // 群聊发消息 RateUpload = "upload" // 帖子插图等上传 RateInteract = "interact" // 投票/抽奖/解锁等互动 RateHidePassword = "hide_password" // 密码隐藏块尝试 ) // 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/分钟 rl.SetLimit(RateChat, 30) // 群聊消息 30/分钟 rl.SetLimit(RateUpload, 20) // 图片上传 20/分钟 rl.SetLimit(RateInteract, 40) // 互动 40/分钟 rl.SetLimit(RateHidePassword, 20) // 密码尝试 20/分钟(按 IP) return rl }