kube-proxy使用了k8s官方工具库中的BoundedFrequencyRunner实现基于事件及时间间隔的配置同步
1 BounderFrequencyRunner构建
1.1 相关核心代码
// name: Runner名称
// func():目标方法
// minInterval:最小时间间隔(2次目标方法调用的最小间隔)
// maxInterval:最大时间间隔(2次目标方法调用的最大间隔,当没有事件时,以最大时间间隔执行)
// burstRuns:允许突发
func NewBoundedFrequencyRunner(name string, fn func(), minInterval, maxInterval time.Duration, burstRuns int) *BoundedFrequencyRunner {
timer := &realTimer{
timer: time.NewTimer(0)} // will tick immediately
<-timer.C() // consume the first tick
return construct(name, fn, minInterval, maxInterval, burstRuns, timer)
}
//construct方法中基于最小时间间隔构建了令牌桶限速器,关键代码如下
qps := float32(time.Second) / float32(minInterval)
bfr.limiter = flowcontrol.NewTokenBucketRateLimiterWithClock(qps, burstRuns, timer)
# 其中rate.Limit(qps)将qps从float32转换为float64
func NewTokenBucketRateLimiterWithClock(qps float32, burst int, c Clock) RateLimiter {
limiter := rate.NewLimiter(rate.Limit(qps), burst)
return newTokenBucketRateLimiter(limiter, c, qps)
}
1.2 qps计算测试
func main() {
duration32 :=float32(time.Second) / float32(3*time.Second)
duration64 :=float64(time.Second) / float64(3*time.Second)
duration32To64 := float64(duration32)
fmt.Println(duration32)
fmt.Println(duration64)
fmt.Println(duration32To64)
}
# 执行结果为
0.33333334
0.3333333333333333
0.3333333432674408
结合代码及上述测试结果,可以发现,计算qps时产生了精度丢失,而在转换类型时,又产生了一次精度丢失,导致了实际使用的limit值大于期望值
注意:实际使用的limit值大于期望值
2 BounderFrequencyRunner Loop
BoundedFrequencyRunner 通过Loop方法运行
2.1 相关核心代码
func (bfr *BoundedFrequencyRunner) Loop(stop <-chan struct{
}) {
klog.V(3).Infof("%s Loop running", bfr.name)
bfr.timer.Reset(bfr.maxInterval)
for {
select {
case <-stop:
bfr.stop()
klog.V(3).Infof("%s Loop stopping", bfr.name)
return
//基于时间
case <-bfr.timer.C(