005_針對於go語言中速率限制的思考

來源:互聯網
上載者:User

標籤:傳值   輸出   代碼   解決方案   怎麼   需求   ++   條件   3.4   

在之前的go語言的速率限制這篇文章裡,我們嘗試了普通的速率限制,和脈衝型速率限制。其中,脈衝型速率限制是放開了限制,裡面有3個請求是一次性到達,然後再按照200ms的速度限制的,之前的代碼如下所示:

package mainimport "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 {<-limiterfmt.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 {<-burstyLimiterfmt.Println("request", req, time.Now())}}

  

最終的輸出是下面這樣,可以看到下面那段輸出的前三次輸出,時間幾乎沒差,這是一次脈衝型速率限制:

request 1 2018-04-17 12:57:02.823975218 +0800 CST m=+0.205374957request 2 2018-04-17 12:57:03.024067833 +0800 CST m=+0.405476106request 3 2018-04-17 12:57:03.220187209 +0800 CST m=+0.601603847request 4 2018-04-17 12:57:03.420175881 +0800 CST m=+0.801601050request 5 2018-04-17 12:57:03.622105704 +0800 CST m=+1.003539485request 1 2018-04-17 12:57:03.622191244 +0800 CST m=+1.003625029request 2 2018-04-17 12:57:03.622210962 +0800 CST m=+1.003644748request 3 2018-04-17 12:57:03.622223153 +0800 CST m=+1.003656939request 4 2018-04-17 12:57:03.82356235 +0800 CST m=+1.205004724request 5 2018-04-17 12:57:04.024178896 +0800 CST m=+1.405629826

  

那我們如果想實現另一種脈衝型速率限制怎麼辦,就是一開始,讓速度變慢,然後再正常請求的,經過思考,代碼改造如下:

package mainimport "fmt"import "time"func main() {k := 0requests := make(chan int, 5)for i := 1; i <= 5; i++ {requests <- i}close(requests)limiter := time.Tick(time.Millisecond * 200)slow := time.Tick(time.Millisecond * 400)for req := range requests {if k < 3 {<-slowk++}<-limiterfmt.Println("request", req, time.Now())}}

  

運行結果如下,可以看到,前三次間隔是400ms,第四次又還原回來間隔200ms:

request 1 2018-04-17 17:04:50.9986303 +0800 CST m=+0.405591505request 2 2018-04-17 17:04:51.395919457 +0800 CST m=+0.802875205request 3 2018-04-17 17:04:51.794626945 +0800 CST m=+1.201577217request 4 2018-04-17 17:04:51.993709916 +0800 CST m=+1.400657453request 5 2018-04-17 17:04:52.196450634 +0800 CST m=+1.603395386

  

我來解釋下代碼邏輯。為了實現需求,我在前面又設定了一個打點器,然後增加判斷,如果k小於3,就從打點器中取值,然後k自增。這樣的話保證了前三次取值慢,後面的取值快。

這時候有人會問了,那例子中是總共兩個打點器,一個是400ms,一個是200ms,為什麼前三次不是400+200總共600ms,而是間隔只有400ms呢?

我來解釋一下,因為代碼運行到<-slow時候是阻塞狀態,通道內沒有值,是需要打點器每隔400ms把值存入slow中,才能繼續啟動並執行。而<-limiter按理說也是阻塞狀態,也需要打點器傳值的。但是別忘了,limiter是200ms,在slow傳值之前,limiter就已經存入值了。所以在if判斷語句結束以後,limiter不用等待傳值,直接取就行了。這樣的話,在if條件執行完後,<-limiter執行是瞬間完成的,不用等待200ms的。

 

以上就是go語言中速率限制的一些思考和改造,在實際工作中,應該還有更加完美的解決方案,期待將來的改進。

 

005_針對於go語言中速率限制的思考

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.