From 94005c8dc80b2124f050478029c830d36c3311c1 Mon Sep 17 00:00:00 2001 From: Edward Date: Thu, 21 May 2020 12:28:53 +0800 Subject: [PATCH] finish rate-limit pattern --- resiliency/07_rate_limiting/rate_limiting.go | 47 +++++++++---------- .../07_rate_limiting/rate_limiting_test.go | 25 +++++++++- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/resiliency/07_rate_limiting/rate_limiting.go b/resiliency/07_rate_limiting/rate_limiting.go index 23282fd..28e4e84 100644 --- a/resiliency/07_rate_limiting/rate_limiting.go +++ b/resiliency/07_rate_limiting/rate_limiting.go @@ -12,22 +12,10 @@ With limiting you can controll resource utilization and maintain quality of serv Go supports rate limiting by using goroutines, channels, and tickers. */ -func rateLimiting(requestQueueSize, allowedBurstCount int) { +func rateLimiting(requestQueue chan int, duration int64, allowedBurstCount int) { - requests := make(chan int, requestQueueSize) - for i := 1; i <= requestQueueSize; i++ { - requests <- i - } - close(requests) - - limiter := time.Tick(200 * time.Millisecond) - - for req := range requests { - <-limiter - fmt.Println("request", req, time.Now()) - } - - //允许的突发数量 + //根据允许的突发数量,创建ch + //只要该队列中有内容,就可以一直取出来,即便ch已经关闭 burstyLimiter := make(chan time.Time, allowedBurstCount) //初始化允许突发的数量 @@ -37,20 +25,29 @@ func rateLimiting(requestQueueSize, allowedBurstCount int) { //控制请求频率的计时器 go func() { - for t := range time.Tick(200 * time.Millisecond) { + for t := range time.Tick(time.Duration(duration) * time.Millisecond) { burstyLimiter <- t } }() - //请求队列 - burstyRequests := make(chan int, requestQueueSize) - for i := 1; i <= requestQueueSize; i++ { - burstyRequests <- i - } - close(burstyRequests) - - for req := range burstyRequests { - <-burstyLimiter + for req := range requestQueue { + <-burstyLimiter //突发控制器是限流的关键 + fmt.Println("request", req, time.Now()) + } +} + +func simpleRateLimiting(duration int64, requestQueueSize int) { + + requests := make(chan int, requestQueueSize) + for i := 1; i <= requestQueueSize; i++ { + requests <- i + } + close(requests) + + limiter := time.Tick(time.Duration(duration) * time.Millisecond) + + for req := range requests { + <-limiter fmt.Println("request", req, time.Now()) } } diff --git a/resiliency/07_rate_limiting/rate_limiting_test.go b/resiliency/07_rate_limiting/rate_limiting_test.go index f51f1b4..1d5d2c6 100644 --- a/resiliency/07_rate_limiting/rate_limiting_test.go +++ b/resiliency/07_rate_limiting/rate_limiting_test.go @@ -1,3 +1,11 @@ +/* + * @Description: https://github.com/crazybber + * @Author: Edward + * @Date: 2020-05-21 12:14:27 + * @Last Modified by: Edward + * @Last Modified time: 2020-05-21 12:27:56 + */ + package ratelimit import ( @@ -11,8 +19,23 @@ With limiting you can controll resource utilization and maintain quality of serv Go supports rate limiting by using goroutines, channels, and tickers. */ +var ( + requestQueueSize = 10 +) + func TestRateLimiting(t *testing.T) { - rateLimiting(5, 3) + //请求队列 + burstyRequests := make(chan int, requestQueueSize) + + for i := 1; i <= requestQueueSize; i++ { + burstyRequests <- i + } + close(burstyRequests) + + //对请求进行限流 + + //200ms允许一次请求,最多同时3个突发 + rateLimiting(burstyRequests, 200, 3) }