使用 rate.Limiter 实现 http 请求限速,通过设置每秒令牌数和突发容量控制 QPS,可封装为自定义客户端或按域名独立限速,避免服务过载。

在golang中实现HTTP请求限速,核心思路是控制单位时间内发出的请求数量。常用方法是利用 令牌桶算法,Go标准库中的 golang.org/x/time/rate 包提供了简单高效的实现方式。以下是具体做法。
使用 rate.Limiter 控制请求频率
rate.Limiter 是 Go 官方提供的限流工具,适合控制每秒请求数(QPS)。你可以为每个 HTTP 客户端或整个服务设置统一的限速规则。
示例:限制每秒最多 5 个请求,突发允许 1 次额外请求:
package main <p>import ( "fmt" "net/http" "time" "golang.org/x/time/rate" )</p><p>func main() { // 每秒填充 5 个令牌,最多容纳 6 个(burst=6) limiter := rate.NewLimiter(5, 6)</p><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">client := &http.Client{Timeout: 10 * time.Second} urls := []string{ "https://httpbin.org/delay/1", "https://httpbin.org/delay/1", "https://httpbin.org/delay/1", } for _, url := range urls { // 请求前等待令牌 if err := limiter.Wait(nil); err != nil { fmt.Printf("请求被取消: %vn", err) continue } resp, err := client.Get(url) if err != nil { fmt.Printf("请求失败: %vn", err) continue } fmt.Printf("响应状态: %sn", resp.Status) resp.Body.Close() }
}
封装带限速的 HTTP 客户端
为了复用和解耦,可以将限速逻辑封装进自定义的 HTTP 客户端结构体中。
立即学习“go语言免费学习笔记(深入)”;
type RateLimitedClient struct { Client *http.Client Limiter *rate.Limiter } <p>func (r <em>RateLimitedClient) Get(url string) (</em>http.Response, error) { if err := r.Limiter.Wait(nil); err != nil { return nil, err } return r.Client.Get(url) }
使用方式:
limitedClient := &RateLimitedClient{ Client: &http.Client{}, Limiter: rate.NewLimiter(2, 2), // 2 QPS } <p>resp, err := limitedClient.Get("<a href="https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635">https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635</a>")
按域名或服务做独立限速
如果请求多个不同服务,建议对每个域名使用独立的限速器,避免相互影响。
可以用 map 缓存每个 host 对应的 limiter,例如:
var hostLimiters = sync.Map{} // key: host, value: *rate.Limiter <p>func getLimiterForHost(host string) <em>rate.Limiter { if limiter, ok := hostLimiters.Load(host); ok { return limiter.(</em>rate.Limiter) } newLimiter := rate.NewLimiter(3, 3) // 不同 host 可配置不同速率 limiter, _ := hostLimiters.LoadOrStore(host, newLimiter) return limiter.(*rate.Limiter) }
发送请求前调用对应 host 的限速器即可。
基本上就这些。通过 golang.org/x/time/rate 结合 HTTP 客户端,可以轻松实现细粒度的请求限速,防止对目标服务器造成压力或触发封禁。关键是根据业务场景合理设置填充速率和突发容量。不复杂但容易忽略。


