Golang Go语言中 uber-go/ratelimit 菜鸡求助

发布于 1周前 作者 caililin 来自 Go语言

Golang Go语言中 uber-go/ratelimit 菜鸡求助

uber 开源的限流算法,代码不多,尝试理解但是没怎么理解。有没有大佬指点一二.主要不理解的点在于这个 for 循环

// Take blocks to ensure that the time spent between multiple
// Take calls is on average time.Second/rate.
func (t *limiter) Take() time.Time {
	newState := state{}
	taken := false
	for !taken {
		now := t.clock.Now()

		previousStatePointer := atomic.LoadPointer(&t.state)
		oldState := (*state)(previousStatePointer)

		newState = state{}
		newState.last = now

		// If this is our first request, then we allow it.
		if oldState.last.IsZero() {
			taken = atomic.CompareAndSwapPointer(&t.state, previousStatePointer, unsafe.Pointer(&newState))
			continue
		}

		// sleepFor calculates how much time we should sleep based on
		// the perRequest budget and how long the last request took.
		// Since the request may take longer than the budget, this number
		// can get negative, and is summed across requests.
		newState.sleepFor += t.perRequest - now.Sub(oldState.last)
		// We shouldn't allow sleepFor to get too negative, since it would mean that
		// a service that slowed down a lot for a short period of time would get
		// a much higher RPS following that.
		if newState.sleepFor < t.maxSlack {
			newState.sleepFor = t.maxSlack
		}
		if newState.sleepFor > 0 {
			newState.last = newState.last.Add(newState.sleepFor)
		}
		taken = atomic.CompareAndSwapPointer(&t.state, previousStatePointer, unsafe.Pointer(&newState))
	}
	t.clock.Sleep(newState.sleepFor)
	return newState.last
}

更多关于Golang Go语言中 uber-go/ratelimit 菜鸡求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

var counter int64

然后如果有多个线程执行下面这个循环,每次 break 都会给 counter 加一
for {
counter0 := atomic.LoadInt64(&counter)
if atomic.CompareAndSwap(&counter, counter0, counter+1) {
break
}
}

这种就是所谓的 lock-free,把它写成用 lock 的形式,再把那几个 if 去掉,这个函数其实就是

func (t *limiter) Take() time.Time {

mutex.Lock()

oldState := t.state
newState = state{}
now := t.clock.Now()
newState.last = now
newState.sleepFor += t.perRequest - now.Sub(oldState.last)

t.state = &newState
mutex.Unlock()

t.clock.Sleep(newState.sleepFor)
return newState.last
}

然后应该很好懂了

更多关于Golang Go语言中 uber-go/ratelimit 菜鸡求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢。第一次在 V2EX 发帖就得到了高效帮助,太棒了

你好,针对你在使用 uber-go/ratelimit 库时遇到的问题,这里提供一些基本的指导和建议,希望能帮助你更好地理解和使用这个库。

uber-go/ratelimit 是一个用于在 Go 语言中实现速率限制的库,它可以帮助你控制对某个资源的访问频率,防止因请求过多而导致的系统崩溃或性能下降。

首先,你需要确保已经正确安装了这个库。你可以通过运行 go get -u go.uber.org/atomicgo get -u go.uber.org/ratelimit 来安装所需的依赖。

接下来,你可以创建一个速率限制器,例如:

import (
    "go.uber.org/ratelimit"
    "time"
)

var lim = ratelimit.New(5) // 每秒允许5个请求

func someFunction() {
    if lim.Allow() {
        // 处理请求
    } else {
        // 速率限制,处理请求失败的情况
    }
}

在这个例子中,ratelimit.New(5) 创建了一个每秒允许5个请求的速率限制器。你可以通过调用 lim.Allow() 来检查是否允许当前请求通过。

如果你遇到了具体的错误或问题,建议查看 uber-go/ratelimit 的官方文档或源代码,了解更详细的使用方法和注意事项。此外,你也可以在相关的开发者社区或论坛上寻求帮助,通常会有经验丰富的开发者愿意提供解答。

希望这些信息对你有所帮助!如果你有更具体的问题,欢迎继续提问。

回到顶部