uber go/ratelimit算法是如何工作的?
我试图理解uber对ratelimit的开源实现,但有点困惑 完整代码如下所示:uber go/ratelimit算法是如何工作的?,go,rate-limiting,Go,Rate Limiting,我试图理解uber对ratelimit的开源实现,但有点困惑 完整代码如下所示: // 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 {
// 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
}
//使用块来确保在多个
//接听电话是平均时间。秒/率。
func(t*限制器)Take()time.time{
newState:=状态{}
假设:=假
因为!吃了{
now:=t.clock.now()
previousStatePointer:=atomic.LoadPointer(&t.state)
oldState:=(*状态)(previousStatePointer)
newState=状态{}
newState.last=现在
//如果这是我们的第一个请求,那么我们允许它。
如果oldState.last.IsZero(){
take=atomic.CompareAndSwapPointer(&t.state,previousStatePointer,unsafe.Pointer(&newState))
持续
}
//sleepFor计算我们应该睡眠的时间
//perRequest预算以及上次请求所用的时间。
//由于请求可能需要比预算更长的时间,此数字
//可以为负数,并在请求之间求和。
newState.sleepFor+=t.perRequest-now.Sub(oldState.last)
//我们不应该让sleepFor变得太消极,因为这意味着
//在短时间内速度大幅降低的服务将获得
//之后的RPS要高得多。
如果newState.sleepFor0{
newState.last=newState.last.Add(newState.sleepFor)
}
take=atomic.CompareAndSwapPointer(&t.state,previousStatePointer,unsafe.Pointer(&newState))
}
t、 clock.Sleep(newState.sleepFor)
返回newState.last
}
我意识到这是一个无锁算法,但我对这个主题知之甚少
如果有人碰巧知道这个算法并给我一些答案/文档/博客,谢谢。我的问题实际上是试图理解为什么这是一个无锁的算法。也许考虑更新你的问题,然后,谢谢你的建议。这不是一个想象中的“无锁算法”。这只是一些模拟自变量的CAS舞蹈。CAS不是非阻塞算法的一部分吗?对不起,我的问题实际上是试图理解为什么这是一个无锁的算法。也许考虑更新你的问题,然后,谢谢你的建议。这不是一个想象中的“无锁算法”。这只是一些模拟互斥的CAS舞蹈。CAS不是非阻塞算法的一部分吗?