golang 框架中限流是限制系统同时处理请求数量,熔断是主动熔断某些服务或操作,防止进一步损坏。限流实现可使用令牌桶算法,熔断可使用熔断器,实战案例有保护 api 的限流和保护微服务中请求的熔断。
Golang 框架中限流和熔断的原理与实现
原理
限流:限制系统同时处理的请求数量,以防止服务器过载。常见的限流算法包括令牌桶算法和漏桶算法。
立即学习“go语言免费学习笔记(深入)”;
熔断:当系统检测到错误请求过多时,主动熔断某些服务或操作,防止进一步的损坏。熔断器通常有三个状态:关闭、开启和半开启。
实现
限流
使用 golang.org/x/time/rate 包实现令牌桶算法:
import "golang.org/x/time/rate"
// 每秒允许的最大请求数
maxRequestsPerSecond := 100
// 限流器
limiter := rate.NewLimiter(rate.Limit(maxRequestsPerSecond), 1)
// 处理请求
func handleRequest() {
if limiter.Allow() {
// 允许处理请求
} else {
// 拒绝请求
}
}
熔断
使用 github.com/afex/hystrix-go 包实现熔断器:
import "github.com/afex/hystrix-go/hystrix"
// 熔断器
hystrix.ConfigureCommand("my-command", hystrix.CommandConfig{
Timeout: 1000,
MaxConcurrentRequests: 10,
ErrorPercentThreshold: 50,
SleepWindow: 5000,
})
// 处理请求
func handleRequest() {
err := hystrix.Do("my-command", func() error {
// 执行请求
return nil
})
if err != nil {
// 请求失败,熔断器关闭
}
}
实战案例
使用限流保护 API
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
limiter := rate.NewLimiter(rate.Every(1*time.Second), 100)
r.GET("/api", func(c *gin.Context) {
if limiter.Allow() {
// 处理请求
} else {
c.AbortWithStatus(429)
}
})
r.Run(":8080")
}
使用熔断保护微服务
package main
import (
"context"
"log"
"time"
hystrix "github.com/afex/hystrix-go/hystrix"
)
func main() {
hystrix.ConfigureCommand("my-command", hystrix.CommandConfig{
Timeout: 100,
MaxConcurrentRequests: 10,
ErrorPercentThreshold: 50,
SleepWindow: 5000,
})
for {
err := hystrix.Do("my-command", func() error {
// 模拟请求执行
time.Sleep(50 * time.Millisecond)
return nil
}, hystrix.WithHystrixRequestContext(context.Background()))
if err != nil {
log.Printf("请求失败: %v", err)
} else {
log.Printf("请求成功")
}
}
}