软件系统限流-2

软件系统限流-1

1. 漏桶算法

package leaky_bucket

import (
    "fmt"
    "time"
)

// 漏桶算法

// LeakyBucket 漏桶算法
type LeakyBucket struct {
    queue chan struct{}
}

// NewLeakyBucket 创建一个漏桶算法
func NewLeakyBucket(bucketSize int) *LeakyBucket {
    return &LeakyBucket{
       queue: make(chan struct{}, bucketSize),
    }
}

// Add 向漏桶中添加一个请求
func (l *LeakyBucket) Add() bool {
    select {
    case l.queue <- struct{}{}:
       return true
    default:
       return false
    }
}

// Remove 从漏桶中移除一个请求
func (l *LeakyBucket) Remove() {
    for range l.queue {
       fmt.Println("Request handled", time.Now().Format("2006-01-02 15:04:05"))
       time.Sleep(100 * time.Millisecond)
    }
}

func main() {
    limiter := leaky_bucket.NewLeakyBucket(10)

    go limiter.Remove() // 模拟处理请求

    for i := 0; i < 15; i++ {
       if limiter.Add() {
          fmt.Println("Request", i+1, "allowed")
       } else {
          fmt.Println("Request", i+1, "rejected")
       }
    }

    time.Sleep(time.Second * 5)

}

        这段代码实现了一个简单的漏桶算法(Leaky Bucket Algorithm),用于流量控制。漏桶算法是一种经典的流量整形和限流算法,通过将请求放入一个固定容量的桶中,并以固定速率从桶中移除请求,来控制请求的速率。 

1.1. 工作原理
  1. 初始化

    1. NewLeakyBucket 函数创建一个新的漏桶,接受一个参数 bucketSize,表示桶的容量。

    2. 使用 make(chan struct{}, bucketSize) 创建一个带缓冲的通道 queue,其缓冲区大小为 bucketSize

  2. 添加请求

    1. Add 方法向漏桶中添加一个请求。

    2. 使用 select 语句尝试向 queue 通道中发送一个空结构体 struct{}{}。如果通道未满,发送成功并返回 true;如果通道已满,发送失败并返回 false

  3. 移除请求

    1. Remove 方法从漏桶中移除请求。

    2. 使用 for range 语句从 queue 通道中读取请求,并处理每个请求,通道关闭的时候,循环会退出。处理请求的过程中,使用 time.Sleep 模拟处理时间。

1.2. 优缺点

优点:

  1. 简单易懂:实现和理解相对简单,不需要复杂的数据结构。

  2. 恒定速率:通过固定的移除速率,能够平滑请求流量,防止突发流量。

  3. 防止过载:通过固定容量的桶,能够防止系统过载。

缺点:

  1. 固定处理速率:处理速率是固定的,无法动态调整,可能不适应瞬时高峰流量。

  2. 单一线程:当前实现中,Remove 方法只能在单一线程中运行,无法利用多核处理能力。

2.1.3 改进方向
  • 动态调整处理速率:可以根据系统负载,动态调整请求的处理速率。【可以加入time.NewTicker】

  • 并发处理:使用多个 goroutine 来处理请求,提高处理能力。

package leaky_bucket

import (
    "fmt"
    "sync"
    "time"
)

type LeakyBucketV2 struct {
    queue    chan struct{}  // 漏桶队列
    stopChan chan struct{}  // 停止信号
    wg       sync.WaitGroup // 等待所有请求处理完成
}

// NewLeakyBucketV2 创建一个漏桶算法
func NewLeakyBucketV2(bucketSize int) *LeakyBucketV2 {
    return &LeakyBucketV2{
       queue:    make(chan struct{}, bucketSize),
       stopChan: make(chan struct{}),
    }
}

// Add 向漏桶中添加一个请求
func (l *LeakyBucketV2) Add() bool {
    select {
    case l.queue <- struct{}{}:
       return true
    default:
       return false
    }
}

// Remove 从漏桶中移除一个请求
func (l *LeakyBucketV2) Remove() {
    for {
       select {
       case <-l.queue:
          l.wg.Add(1)
          go func() {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SAO&asuna

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值