在 golang 高并发场景中,限流和熔断可保护系统免遭过载:限流通过限制请求数量,防止系统超负荷,例如使用令牌桶算法。熔断在服务故障或负荷过高时关闭访问,例如使用熔断器模式,当失败请求达到阈值,熔断器打开,一段时间后关闭。实战应用:api 网关的限流,限制后端服务请求微服务中的熔断机制,避免级联故障

在 Golang 高并发场景中实现限流和熔断
在高并发场景中,处理大量请求时,限流和熔断至关重要。它们可以保护系统免于过载和故障。
限流
立即学习“go语言免费学习笔记(深入)”;
限流限制了在给定时间内可以处理的请求数量。这可以防止系统因超出其处理能力而崩溃。
令牌桶算法:限制一段时间内可以处理的请求数量。它通过创建一个有固定数量令牌的桶来实现,每个请求从桶中获取令牌。当桶中没有令牌时,请求将被拒绝。
import (
"golang.org/x/sync/singleflight"
"time"
)
// 令牌桶限流器
type TokenBucketLimiter struct {
maxTokens int
currentTokens int
refillRate float64
refillTimer *time.Timer
}
func (l *TokenBucketLimiter) Acquire(count int) (success bool) {
if l.currentTokens >= count {
l.currentTokens -= count
return true
}
if l.refillTimer == nil {
l.refillTimer = time.NewTimer(0)
}
if ok := l.refillTimer.Stop(); !ok {
<-l.refillTimer.C
}
l.currentTokens += int(time.Since(l.refillTimer.Stop()) * l.refillRate)
return l.Acquire(count)
}
func (l *TokenBucketLimiter) SetRefillRate(rate float64) {
l.refillRate = rate
l.refillTimer.Reset(time.Duration(1000 / rate))
}
func main() {
limiter := TokenBucketLimiter{maxTokens: 10, refillRate: 2}
for i := 0; i < 20; i++ {
if success := limiter.Acquire(2); success {
fmt.Println("请求", i, "通过限流器")
} else {
fmt.Println("请求", i, "被限流器拒绝")
}
}
}熔断
熔断在一段时间内关闭对服务的访问。当服务出现故障或负荷过高时,这将防止请求继续涌入。
熔断器模式:当失败请求达到一定阈值时,熔断器打开,对服务的访问被关闭。当一段时间后恢复失败请求的数量后,熔断器再次关闭,访问恢复。
import (
"context"
"fmt"
"github.com/sony/gobreaker"
"time"
)
// 业务逻辑函数
func serviceCall() error {
// 模拟失败率为 50% 的业务调用
if rand.Intn(2) == 0 {
return errors.New("模拟错误")
}
return nil
}
func main() {
// 创建熔断器(超时:3 秒,最大失败次数:5 次,失败率阈值:50%)
breaker := gobreaker.NewCircuitBreaker(gobreaker.Settings{
Timeout: 3 * time.Second,
MaxRequests: 5,
Interval: time.Second,
OnStateChange: nil,
ResetTimeout: 5 * time.Second,
ReadyToTrip: func(counts gobreaker.Counts) bool { return counts.TotalFailures >= 5 },
AllowIfClosed: func(counts gobreaker.Counts) bool { return counts.TotalFailures < 5 },
})
ctx := context.Background()
for i := 0; i < 11; i++ {
// 使用熔断器包装 serviceCall 函数
result, err := breaker.Execute(ctx, serviceCall)
// 根据返回值判断熔断器状态
if err != nil {
if _, ok := err.(gobreaker.TripReason); ok {
fmt.Println("服务已熔断")
} else {
fmt.Println("请求失败:", err)
}
} else {
fmt.Println("请求成功:", result)
}
time.Sleep(1 * time.Second)
}
}实战案例
在实际的高并发场景中,可以将限流和熔断应用于以下场景:
注意
以上就是在Golang高并发场景中如何进行限流和熔断处理?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号