限流与熔断是保障高并发Golang服务稳定的关键,通过rate.Limiter实现令牌桶限流,gobreaker库实现熔断机制,结合中间件可提升复用性,有效防止系统雪崩。

在高并发的Golang服务中,请求限流与熔断是保障系统稳定性的关键手段。当流量突增或下游服务异常时,若不加以控制,可能导致服务雪崩。合理的限流能防止系统过载,而熔断机制可在依赖服务不可用时快速失败,避免资源耗尽。
限流:控制请求速率
限流的核心目标是限制单位时间内处理的请求数量,常用算法包括令牌桶、漏桶和计数器。Golang标准库中的 golang.org/x/time/rate 提供了基于令牌桶的简单限流实现。
示例:使用 rate.Limiter 限制每秒最多10个请求
package main
<p>import (
"fmt"
"golang.org/x/time/rate"
"net/http"
"time"
)</p><p>var limiter = rate.NewLimiter(10, 1) // 每秒10个令牌,突发允许1个</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/00968c3c2c15" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">go语言免费学习笔记(深入)</a>”;</p><p>func limitedHandler(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
return
}
fmt.Fprintf(w, "Request processed at %v", time.Now())
}</p><p>func main() {
http.HandleFunc("/api", limitedHandler)
http.ListenAndServe(":8080", nil)
}
对于分布式服务,可结合 Redis 实现全局限流,例如使用滑动窗口算法(如 Redis 的 INCR 配合过期时间)统计请求次数。
熔断:防止级联故障
熔断机制模仿电路保险丝,在依赖服务持续失败时主动拒绝请求,给系统恢复时间。常用状态有“关闭”、“开启”和“半开”。Go 社区广泛使用的熔断库是 sony/gobreaker。
示例:使用 gobreaker 熔断外部 HTTP 调用
package main
<p>import (
"context"
"errors"
"fmt"
"github.com/sony/gobreaker"
"net/http"
"time"
)</p><p>var cb = &gobreaker.CircuitBreaker{
Name: "ExternalAPI",
MaxRequests: 3,
Interval: 5 <em> time.Second,
Timeout: 10 </em> time.Second,
ReadyToTrip: func(counts gobreaker.Counts) bool {
return counts.ConsecutiveFailures > 3
},
}</p><p>func callExternalAPI() (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()</p><pre class="brush:php;toolbar:false;">req, _ := http.NewRequestWithContext(ctx, "GET", "https://httpbin.org/status/500", nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
if resp.StatusCode != 200 {
return "", errors.New("server error")
}
return "success", nil
}
func handler(w http.ResponseWriter, r *http.Request) { result, err := cb.Execute(func() (interface{}, error) { res, err := callExternalAPI() return res, err }) if err != nil { http.Error(w, "Service unavailable", http.StatusServiceUnavailable) return } fmt.Fprintf(w, "Result: %v", result) }
熔断器参数需根据实际场景调整:超时时间不宜过长,失败阈值应结合业务容忍度设定。
整合进中间件提升复用性
将限流与熔断逻辑封装为 HTTP 中间件,可统一应用于多个路由。
func RateLimitMiddleware(next http.Handler) http.Handler {
limiter := rate.NewLimiter(5, 1)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
return
}
next.ServeHTTP(w, r)
})
}
<p>func CircuitBreakerMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := cb.Execute(func() (interface{}, error) {
next.ServeHTTP(w, r)
return nil, nil
})
if err != nil {
http.Error(w, "Service down", http.StatusServiceUnavailable)
}
})
}
注册时链式调用:
http.Handle("/api", RateLimitMiddleware(CircuitBreakerMiddleware(handler)))
基本上就这些。合理配置限流和熔断策略,能显著提升服务的容错能力和可用性。


















