client-go是如何实现一个指数回退请求工具的

541 阅读1分钟

概述

k8s.io/client-go/util/retry/util.go 定义了func RetryOnConflict(backoff wait.Backoff, fn func() error)方法,里面用到了wait.Backoff等相关方法,实现指数回退重试。

实现

指数回退的参数设计:

  • base时间(或者下一次时间)
  • 指数
  • 随机波动参数
  • 剩余尝试次数
  • 最大等待时间(时间帽)
type Backoff struct {
    Duration time.Duration
    Factor float64
    Jitter float64
    Steps int
    Cap time.Duration
}

算法细节:

func (b *Backoff) Step() time.Duration {
	if b.Steps < 1 {
		if b.Jitter > 0 {
			return Jitter(b.Duration, b.Jitter)
		}
		return b.Duration
	}
	b.Steps--

	duration := b.Duration

	// calculate the next step
	if b.Factor != 0 {
		b.Duration = time.Duration(float64(b.Duration) * b.Factor)
		if b.Cap > 0 && b.Duration > b.Cap {
			b.Duration = b.Cap
			b.Steps = 0
		}
	}

	if b.Jitter > 0 {
		duration = Jitter(duration, b.Jitter)
	}
	return duration
}

参考

staging/src/k8s.io/apimachinery/pkg/util/wait/wait.go