client-go和golang源码中的技巧( 五 )
var DefaultRetry = wait.Backoff{Steps:5,Duration: 1 * time.Second,Factor:0,Jitter:0.5,}结果:2019-07-05 10:21:49.5993445 +0800 CST m=+2.3826691012019-07-05 10:21:50.9026701 +0800 CST m=+3.6859947012019-07-05 10:21:52.3759019 +0800 CST m=+5.1592264012019-07-05 10:21:53.7086265 +0800 CST m=+6.4919510012019-07-05 10:21:54.9283913 +0800 CST m=+7.711715901timed out waiting for the condition=> Factor非0且Jitter为0时 , 对duration的调整如下
if b.Factor != 0 {b.Duration = time.Duration(float64(b.Duration) * b.Factor)if b.Cap > 0i < 20; i++ {err := l.Wait(ctx)if nil != err{fmt.Println(err)fmt.Println(time.Since(start))return}go f(ctx)}fmt.Println(time.Since(start))}结果:5.0000404s下例中 , 如果每秒处理的令牌小于2 , 调度频率为实际执行频率(每秒一次)
func main(){l := rate.NewLimiter(2, 10)ctx,cancel := context.WithCancel(context.Background())defer cancel()f:= func(ctx context.Context) error{select {case <-ctx.Done():return ctx.Err()default:}time.Sleep(1*time.Second)return nil}start := time.Now()for i := 0; i < 20; i++ {err := l.Wait(ctx)if nil != err{fmt.Println(err)fmt.Println(time.Since(start))return}f(ctx)}fmt.Println(time.Since(start))}结果:20.0107691sWaitN用于判断是否可以同时执行n个事件 , 每次消耗n个令牌 。 如下例子的总时间算法为:(5*6-10)/2=10
import ("context""fmt""golang.org/x/time/rate""time")func main(){l := rate.NewLimiter(2, 10)ctx,cancel := context.WithCancel(context.Background())defer cancel()f:= func(ctx context.Context) error{select {case <-ctx.Done():return ctx.Err()default:}return nil}start := time.Now()for i := 0; i < 6; i++ {err := l.WaitN(ctx,5)if nil != err{fmt.Println(err)fmt.Println(time.Since(start))return}f(ctx)}fmt.Println(time.Since(start))}结果:10.0011304s读取yaml文件
假设yaml文件内容如下 , yaml文件中的每个首字母必须小写 。 PS:yaml文件中的所有字符建议都小写
scrapeInterval: 60endpoints:- endpoint: cn-shanghai.log.aliyuncs.comaccessKeyID: LTAI2KSu0MDauu2raccessKeySecret: D3m0j7vDmrAWf33SFUh3LJRF1QGgTuproject: avacar-slb-slslogstore: avacar-slsconsumerGroupName: endCursorconsumerName: endConsumer1cursorPosition: END_CURSOR在代码中定义对应的解析结构体 , 结构体成员首字母大写 , 注意每个元素后面的yaml对应的字符串需要与yaml文件中的元素对应 , 大小写一致 。
type Config struct {ScrapeInterval int32Endpoints []Endpoints`yaml: "endpoints"`}type Endpoints struct {Endpoint string `yaml:"endpoint"`AccessKeyID string `yaml:"accessKeyID"`AccessKeySecret string `yaml:"accessKeySecret"`Project string `yaml:"project"`Logstore string `yaml:"logstore"`ConsumerGroupName string `yaml:"consumerGroupName"`ConsumerName string `yaml:"consumerName"`CursorPosition string `yaml:"cursorPosition"`}使用如下方式即可将yaml文件的内容提取出来 , 即config
var config ConfigconfigContent, err := ioutil.ReadFile("D:\\test.yaml")if err != nil {log.Panic("open file failed")return}yaml.Unmarshal(configContent, i < b.N; i++ {for j := 0; j < 10000; j++ {s = pool.Get().(*S)s.num = 1s.num++pool.Put(s)}}}func BenchmarkWithNoPool(b *testing.B) {var s *Sfor i := 0; i < b.N; i++ {for j := 0; j < 10000; j++ {s = &S{num: 1}s.num++}}}func main(){t1 := time.Now().Nanosecond()BenchmarkWithPool(&testing.B{N:10})t2 := time.Now().Nanosecond() - t1fmt.Println("t2 =",t2)t3 := time.Now().Nanosecond()BenchmarkWithNoPool(&testing.B{N:10})t4 := time.Now().Nanosecond() - t3fmt.Println("t4 =",t4)}}结果:
t2 = 1992800t4 = 999000
从下面可以看出 , put和get是按照顺序一对一的 , 如果get完 , 则调用New函数创建一个新的元素返回
// 建立对象var pipe = &sync.Pool{New:func()interface{}{return "Hello,BeiJing"}}// 放入pipe.Put("Hello,World1")pipe.Put("Hello,World2")pipe.Put("Hello,World3")// 取出log.Println(pipe.Get())log.Println(pipe.Get())log.Println(pipe.Get())// 再取就没有了,会自动调用NEWlog.Println(pipe.Get())结果:
2019/12/02 15:24:47 Hello,World12019/12/02 15:24:47 Hello,World22019/12/02 15:24:47 Hello,World32019/12/02 15:24:47 Hello,BeiJing
参考:
作者: charlieroro
出处:
- 中国|浅谈5G移动通信技术的前世和今生
- 芯片|华米GTS2mini和红米手表哪个好 参数功能配置对比
- 桌面|日常使用的软件及网站分享 篇一:几个动态壁纸软件和静态壁纸网站:助你美化你的桌面
- 二维码|村网通?澳大利亚一州推出疫情追踪二维码 还考虑采用人脸识别和地理定位
- 不到|苹果赚了多少?iPhone12成本不到2500元,华为和小米的利润呢?
- 机器人|网络里面的假消息忽悠了非常多的小喷子和小机器人
- 华为|骁龙870和骁龙855区别都是7nm芯片吗 性能对比评测
- 花15.5亿元与中粮包装握手言和 加多宝离上市又进一步?|15楼财经 | 清远加多宝
- 和谐|人民日报海外版今日聚焦云南西双版纳 看科技如何助力人象和谐
- 内容|浅谈内容行业的一些规律和壁垒,聊聊电商平台孵化小红书难点(外部原因)
