• 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
  • 相关阅读:
    Java 图片处理——如何生成高清晰度而占有磁盘小的缩略图
    Java文件IO操作应该抛弃File拥抱Paths和Files
    什么是内存(一):存储器层次结构
    mysql 锁
    Mysql索引面试题
    node.js中对同步,异步,阻塞与非阻塞的理解
    mysql 快照读 当前度
    mysql 联合索引
    redis 分布式锁(单机)
    docker 环境搭建redis集群相关问题
  • 原文地址:https://www.cnblogs.com/wangjq19920210/p/15349766.html
Copyright © 2020-2023  润新知