深入解析Golang中的goroutines、channels与tickers:从基础到高级应用

发表时间: 2024-06-03 20:19

在Golang中,我们可以使用goroutines, channels, tickers轻松的建立一个限流器。

速率限制是控制资源利用和维护服务质量的重要机制。Go 语言通过 goroutines, channels, and tickers优雅地支持速率限制。官网上提供了一个具体示例(
https://gobyexample.com/rate-limiting),代码如下:

package mainimport (    "fmt"    "time")func main() {    //模拟5个请求    requests := make(chan int, 5)    for i := 1; i <= 5; i++ {        requests <- i    }    close(requests)        // 创建一个每200毫秒就触发一次的    limiter := time.Tick(200 * time.Millisecond)    for req := range requests {        // 每200毫秒触发一次        <-limiter        fmt.Println("request", req, time.Now())    }        // 创建有3个缓冲的channel    burstyLimiter := make(chan time.Time, 3)        // 向channel中添加3个初始值    for i := 0; i < 3; i++ {        burstyLimiter <- time.Now()    }        // 启动一个新的goroutine向channel添加值    go func() {        for t := range time.Tick(200 * time.Millisecond) {            burstyLimiter <- t        }    }()        // 模拟5个请求    burstyRequests := make(chan int, 5)    for i := 1; i <= 5; i++ {        burstyRequests <- i    }    close(burstyRequests)        // 限流器开始执行的3个请求会同时到达,后面会每200毫秒执行一次    for req := range burstyRequests {        <-burstyLimiter        fmt.Println("burstyRequest", req, time.Now())    }}

上面的代码展示两种限流使用,一种是没有带缓冲的,每200毫秒只能处理一个请求。一种是带缓冲的,最开始的3个请求会立即执行,后续的请求依然会按照每200毫秒执行一次。运行上面的代码得到的输出如下:

request 1 2024-06-03 20:13:12.7117775 +0800 CST m=+0.215562501request 2 2024-06-03 20:13:12.9074885 +0800 CST m=+0.411273501request 3 2024-06-03 20:13:13.1030114 +0800 CST m=+0.606796401request 4 2024-06-03 20:13:13.2986761 +0800 CST m=+0.802461101request 5 2024-06-03 20:13:13.5114099 +0800 CST m=+1.015194901burstyRequest 1 2024-06-03 20:13:13.5114099 +0800 CST m=+1.015194901burstyRequest 2 2024-06-03 20:13:13.5114099 +0800 CST m=+1.015194901burstyRequest 3 2024-06-03 20:13:13.5114099 +0800 CST m=+1.015194901burstyRequest 4 2024-06-03 20:13:13.7224927 +0800 CST m=+1.226277701burstyRequest 5 2024-06-03 20:13:13.9186188 +0800 CST m=+1.422403801

从输出的日志中我们刚刚说法得到了验证。request的5个请求时每200毫秒执行一次,burstyRequest的前3个是同时执行,后面两个是按照200毫秒一次执行的 。