经手的一部分项目使用了rate.Limiter
作为限流器, 但是使用了atomic.Value
包裹. 猜测本意可能是为了多协程安全, 但实际上rate.Limiter
本身就支持多协程访问. 最终导致了线上限流器行为与预期不符(大约超过限流2倍左右). 在更新限流器限流的时候, 应该使用 SetLimit
或 SetLimitAt
来更新限流配置.
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
| func main() { limiter := rate.NewLimiter(rate.Limit(50000), 10) limiterStore.Store(limiter) ctx := context.Background()
go func() { for { time.Sleep(time.Second * 1) fmt.Printf("count: %v\n", count) } }()
go func() { for { time.Sleep(time.Second * 20) newLimiter := rate.NewLimiter(rate.Limit(50000), 10) limiterStore.Store(newLimiter) } }()
for i := 0; i < 1; i++ { go func() { for { beginTs := time.Now() for j := 0; j < 10000; j++ { _ = limiterStore.Load().(*rate.Limiter).Wait(ctx) } duration := time.Since(beginTs) fmt.Printf("dur: %v\n", duration.Nanoseconds())
count++ } }() }
time.Sleep(time.Hour * 24) }
|