035_go语言中的速率限制
代码演示
package main import "fmt" import "time" func main() { requests := make(chan int, 5) for i := 1; i <= 5; i++ { requests <- i } close(requests) limiter := time.Tick(time.Millisecond * 200) for req := range requests { <-limiter fmt.Println("request", req, time.Now()) } burstyLimiter := make(chan time.Time, 3) for i := 0; i < 3; i++ { burstyLimiter <- time.Now() } go func() { for t := range time.Tick(time.Millisecond * 200) { burstyLimiter <- t } }() burstyRequests := make(chan int, 5) for i := 1; i <= 5; i++ { burstyRequests <- i } close(burstyRequests) for req := range burstyRequests { <-burstyLimiter fmt.Println("request", req, time.Now()) } }
代码运行结果
request 1 2018-04-17 12:57:02.823975218 +0800 CST m=+0.205374957 request 2 2018-04-17 12:57:03.024067833 +0800 CST m=+0.405476106 request 3 2018-04-17 12:57:03.220187209 +0800 CST m=+0.601603847 request 4 2018-04-17 12:57:03.420175881 +0800 CST m=+0.801601050 request 5 2018-04-17 12:57:03.622105704 +0800 CST m=+1.003539485 request 1 2018-04-17 12:57:03.622191244 +0800 CST m=+1.003625029 request 2 2018-04-17 12:57:03.622210962 +0800 CST m=+1.003644748 request 3 2018-04-17 12:57:03.622223153 +0800 CST m=+1.003656939 request 4 2018-04-17 12:57:03.82356235 +0800 CST m=+1.205004724 request 5 2018-04-17 12:57:04.024178896 +0800 CST m=+1.405629826
代码解读
- go语言利用通道,协程,打点器来实现速率限制
- 首先我们利用打点器做了一个limiter通道,该通道每200ms接收一个值,将该通道置于requests的任务前,就起到了限制作用
- 可以利用缓冲通道,来进行脉冲型的速率限制,即在不改变原来每200ms接收值的大前提下,进行一次短的脉冲
- 我们设置了burstyLimiter的缓冲通道,里面存入3个值,并且在开启了一个协程,每200ms存入一个值
- 同样burstyRequests通道中有5个任务,我们把burstyLimiter放于burstyRequests任务前
- 当执行任务时,首先要有一次脉冲将burstyLimiter里的值全部取出,然后再每200ms一次的进行任务读取