Go Wiki:速率限制
若要限制每单位时间的操作速率,请使用 time.Ticker。这适用于每秒几十个操作的速率。对于更高的速率,建议使用令牌桶速率限制器,例如 golang.org/x/time/rate.Limiter(还可以在 pkg.go.dev 中搜索 rate limit)。
import "time"
const rateLimit = time.Second / 10 // 10 calls per second
// Client is an interface that calls something with a payload.
type Client interface {
Call(*Payload)
}
// Payload is some payload a Client would send in a call.
type Payload struct {}
// RateLimitCall rate limits client calls with the payloads.
func RateLimitCall(client Client, payloads []*Payload) {
throttle := time.Tick(rateLimit)
for _, payload := range payloads {
<-throttle // rate limit our client calls
go client.Call(payload)
}
}
若要允许一些突发,请为节流添加一个缓冲区
import "time"
const rateLimit = time.Second / 10 // 10 calls per second
// Client is an interface that calls something with a payload.
type Client interface {
Call(*Payload)
}
// Payload is some payload a Client would send in a call.
type Payload struct {}
// BurstRateLimitCall allows burst rate limiting client calls with the
// payloads.
func BurstRateLimitCall(ctx context.Context, client Client, payloads []*Payload, burstLimit int) {
throttle := make(chan time.Time, burstLimit)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
go func() {
ticker := time.NewTicker(rateLimit)
defer ticker.Stop()
for t := range ticker.C {
select {
case throttle <- t:
case <-ctx.Done():
return // exit goroutine when surrounding function returns
}
}
}()
for _, payload := range payloads {
<-throttle // rate limit our client calls
go client.Call(payload)
}
}
此内容是 Go Wiki 的一部分。