kube-proxy BoundedFrequencyRunner导致死循环分析

本文深入分析了kube-proxy中BoundedFrequencyRunner导致的死循环问题,问题源于浮点数精度误差,使得限速逻辑出错,进而造成CPU 100%。文章详细复现了问题,并提出解决方案,建议调整minInterval为2的指数来避免精度问题。
摘要由CSDN通过智能技术生成

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(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值