client-go 和 golang 源码中的技巧

参考链接:https://www.cnblogs.com/charlieroro/p/11112526.html

1.实现了对golang map的key的处理,如计算交集,并集等。

package main

import (
    "fmt"
    "k8s.io/apimachinery/pkg/util/sets"
)

func main(){
    map1 := map[string]int{"aaa":1,"bbb":2,"ccc":3}
    map2 := map[string]int{"ccc":1,"ddd":2,"eee":3}
    newmap1 := sets.StringKeySet(map1)
    newmap2 := sets.StringKeySet(map2)
    fmt.Println(newmap1.List(),newmap2.List())
    fmt.Println(newmap1.HasAny(newmap2.List()...)) //3个点用于把数组打散为单个元素
}结果:true

2.k8s.io/apimachinery/pkg/util/wait/wait.go

函数:func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error

ExponentialBackoff : 可以实现在函数执行错误后实现以指数退避方式的延时重试。ExponentialBackoff内部使用的是time.Sleep

ExponentialBackoff的首个入参Backoff如下:

  • Duration:表示初始的延时时间
  • Factor:指数退避的因子
  • Jitter:可以看作是偏差因子,该值越大,每次重试的延时的可选区间越大
  • Steps:指数退避的步数,可以看作程序的最大重试次数
  • Cap:用于在Factor非0时限制最大延时时间和最大重试次数,为0表示不限制最大延时时间
type Backoff struct {
    // The initial duration.
    Duration time.Duration
    // Duration is multiplied by factor each iteration. Must be greater
    // than or equal to zero.
    Factor float64
    // The amount of jitter applied each iteration. Jitter is applied after
    // cap.
    Jitter float64
    // The number of steps before duration stops changing. If zero, initial
    // duration is always used. Used for exponential backoff in combination
    // with Factor.
    Steps int
    // The returned duration will never be greater than cap *before* jitter
    // is applied. The actual maximum cap is `cap * (1.0 + jitter)`.
    Cap time.Duration
}

当Factor和Jitter都为0时,可以看到调度周期是相同的,即Duration的值(1s)。

import (
    "fmt"
    "k8s.io/apimachinery/pkg/util/wait"
    "time"
)


func main(){
    var DefaultRetry = wait.Backoff{
        Steps:    5,
        Duration: 1 * time.Second,
        Factor:   0,
        Jitter:   0,
    }

    fmt.Println(wait.ExponentialBackoff(DefaultRetry,func() (bool, error){
        fmt.Println(time.Now())
        return false,nil
    }))
}

结果:
2019-07-05 10:17:33.9610108 +0800 CST m=+0.079831101
2019-07-05 10:17:34.961132 +0800 CST m=+1.079952301
2019-07-05 10:17:35.961512 +0800 CST m=+2.080332301
2019-07-05 10:17:36.9625144 +0800 CST m=+3.081334701
2019-07-05 10:17:37.9636334 +0800 CST m=+4.082453701
timed out waiting for the condition

Factor为1时,可以看到函数执行间隔均为1s

var DefaultRetry = wait.Backoff{
    Steps:    5,
    Duration: 1 * time.Second,
    Factor:   1,
    Jitter:   0,
}

结果:
2019-07-05 10:28:50.8481017 +0800 CST m=+2.363983901
2019-07-05 10:28:51.8482274 +0800 CST m=+3.364109601
2019-07-05 10:28:52.8482359 +0800 CST m=+4.364118201
2019-07-05 10:28:53.848687 +0800 CST m=+5.364569301
2019-07-05 10:28:54.849409 +0800 CST m=+6.365291201
timed out waiting for the condition

调整Factor为3,预期延时时间为1s,3s,9s,27s,从测试结果看与预期相符

var DefaultRetry = wait.Backoff{
    Steps:    5,
    Duration: 1 * time.Second,
    Factor:   3,
    Jitter:   0,
}

结果:
2019-07-05 10:35:06.9030165 +0800 CST m=+0.077746101
2019-07-05 10:35:07.9038392 +0800 CST m=+1.078568701
2019-07-05 10:35:10.9038733 +0800 CST m=+4.078602901
2019-07-05 10:35:19.9042141 +0800 CST m=+13.078943601
2019-07-05 10:35:46.904647 +0800 CST m=+40.079376501
timed out waiting for the condition

wait库的第二组

func Poll(interval, timeout time.Duration, condition ConditionFunc) error 
func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error 
func PollInfinite(interval time.Duration, condition ConditionFunc) error 
func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) error 
func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error 
func PollImmediateUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error

Poll表示以interval的周期执行condition函数,直到timeout超时或condition返回true/err非空。

wait.Poll和wait.Until使用上还是有些类似的,区别在于一个使用timeout限制超时时间,一个使用chan提供主动停止调度。

import (
    "fmt"
    "k8s.io/apimachinery/pkg/util/wait"
    "time"
)


func main(){

    wait.Poll(time.Second, time.Second*5, func() (done bool, err error) {
        fmt.Println(time.Now())
        return false,nil
    })

结果:
2019-07-05 13:43:31.2622405 +0800 CST m=+1.069324901
2019-07-05 13:43:32.2619663 +0800 CST m=+2.069050701
2019-07-05 13:43:33.2626114 +0800 CST m=+3.069695801
2019-07-05 13:43:34.2626876 +0800 CST m=+4.069772001
2019-07-05 13:43:35.2624168 +0800 CST m=+5.069501201
2019-07-05 13:43:35.2624168 +0800 CST m=+5.069501201