最新公告
  • 欢迎您光临码农资源网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!加入我们
  • 在Golang高并发场景中如何进行限流和熔断处理?

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

    在Golang高并发场景中如何进行限流和熔断处理?

    在 Golang 高并发场景中实现限流和熔断

    在高并发场景中,处理大量请求时,限流和熔断至关重要。它们可以保护系统免于过载和故障。

    限流

    限流限制了在给定时间内可以处理的请求数量。这可以防止系统因超出其处理能力而崩溃。

    • 令牌桶算法:限制一段时间内可以处理的请求数量。它通过创建一个有固定数量令牌的桶来实现,每个请求从桶中获取令牌。当桶中没有令牌时,请求将被拒绝。

      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"
        "<a style='color:#f60; text-decoration:underline;' href="https://www.codesou.cn/" target="_blank">git</a>hub.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)
        }
      }

    实战案例

    在实际的高并发场景中,可以将限流和熔断应用于以下场景:

    • API 网关:在 API 网关层进行限流,限制对后端服务的请求数量,防止后端服务过载。
    • 微服务:在微服务中使用熔断机制,当某个服务出现故障时,将对该服务的访问关闭,避免级联故障。

    注意

    • 限流和熔断的具体参数需要根据实际系统需求和性能调优。
    • 熔断策略并不能完全防止系统过载,在极端情况下仍有可能发生故障。
    想要了解更多内容,请持续关注码农资源网,一起探索发现编程世界的无限可能!
    本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
    如有侵权请发送邮件至1943759704@qq.com删除

    码农资源网 » 在Golang高并发场景中如何进行限流和熔断处理?
    • 7会员总数(位)
    • 25846资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 294稳定运行(天)

    提供最优质的资源集合

    立即查看 了解详情