mohuishou / blogComment

mohuishou's blog comment
0 stars 0 forks source link

post/go-training-week6-3-token-bucket-2 #245

Closed utterances-bot closed 2 years ago

utterances-bot commented 3 years ago

Go可用性(三) 限流2: 令牌桶的实现 rate/limt - Mohuishou

mohuishou 的 技术博客, 关注云原生, Go, K8s, Docker, 微服务等技术

https://lailin.xyz/post/go-training-week6-3-token-bucket-2.html

fbbin commented 3 years ago

// 注释掉下面两行,最后结果还剩 8 个 token l.ReserveN(t2, 2) // 桶里还有 -5 个 这里为什么是-5个啊?上面t1后还剩-4个,过了200ms,产生了2个,变成-2个,然后预约2个,不是应该-4个么?

mohuishou commented 3 years ago

@fbbin 因为上一步还剩下 -4 个,然后这段时间(t1 到 t2 只过了 100ms)生产了 1 个,又预约了 2 个,所以是 -4+1-2 = -5

shanghai-Jerry commented 3 years ago

time.Sleep(100 * time.Millisecond)

go func() {
    defer wg.Done()
    // 正常情况下,这个要等 1.2 s 才能执行,但是我们前面都取消了
    // 这个是不是应该就只需要等 200ms 就执行了
    ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
    defer cancel()
    l.WaitN(ctx, 2)
    fmt.Printf("[2] cost: %s\n", time.Since(t))
}()

这个go func 上面的 time.Sleep 这个函数在某种程度上影响了golang调度器的执行顺序。 这个sleep函数的作用我猜测应该是: 想让 [1] cost 所在的goroutine先执行,然后看waitN(10) 是不是在cancel后会影响[2] cost 所在goroutine的等待时间, 如果你把休眠时间改成200,就只需要等 200ms 就执行了,而不是1.2s。 这说明了什么问题呢?

mohuishou commented 3 years ago

@shanghai-Jerry 这个是现有令牌桶实现的一个缺陷,就是第一个任务取消了,但是第二个等待中的任务的时间不会被提前