package limiter import ( "sync" "golang.org/x/time/rate" ) func init() { SetupIpRateLimiter() } type IpRateLimiter struct { ips map[string]*rate.Limiter mu *sync.RWMutex r rate.Limit // float64 速率 1秒 b int // 并发 1次请求 } var RateLimiter *IpRateLimiter // 创建一个RateLimiter func SetupIpRateLimiter() error { var r rate.Limit = 10 b := 1 RateLimiter = &IpRateLimiter{ ips: make(map[string]*rate.Limiter), mu: &sync.RWMutex{}, r: r, // 速率 b: b, // 并发 } return nil } // 添加一个ip到map func (i *IpRateLimiter) AddIp(ip string) *rate.Limiter { i.mu.Lock() defer i.mu.Unlock() limiter := rate.NewLimiter(i.r, i.b) i.ips[ip] = limiter return limiter } // 通过ip得到limiter func (i *IpRateLimiter) GetLimiter(ip string) *rate.Limiter { i.mu.Lock() limiter, exists := i.ips[ip] if !exists { i.mu.Unlock() // 注意:这里面也上了锁,所以当前的锁要先释放,不然死锁 return i.AddIp(ip) } // 这里不能忘 i.mu.Unlock() return limiter }