In the previous go language rate limiting article, we tried the normal rate limit, and the pulse rate limit. wherein, the pulse rate limit is the release of the limit, there are 3 requests are one-time arrival, and then at 200ms speed limit, the previous code is as follows:
Package Mainimport "FMT" import "Time" Func main () {requests: = Do (chan int, 5) for I: = 1; I <= 5; i++ {requests <- I}close (requests) limiter: = time. Tick (Time.millisecond *) 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 *) {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 ())}}
The final output is the following, you can see the output below the first three times the output, the time is almost no difference, this is a pulse rate limit:
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.405 476106request 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.6222 23153 +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
What if we want to achieve another type of pulse rate limit, that is, at the beginning, let the speed slow, then the normal request, after thinking, the code is modified as follows:
Package Mainimport "FMT" import "Time" Func Main () {k: = 0requests: = Do (chan int, 5) for I: = 1; I <= 5; i++ {Requests <-I}close (requests) limiter: = time. Tick (Time.millisecond *) Slow: = time. Tick (Time.millisecond *) for req: = Range Requests {if K < 3 {<-slowk++}<-limiterfmt. PRINTLN ("Request", req, time.) Now ())}}
The result is as follows, you can see, the first three times interval is 400ms, the fourth time and restore back interval 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.80287 5205request 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
Let me explain the code logic. In order to achieve the requirements, I set up a device in front, and then increase the judgment, if K is less than 3, from the RBI to take the value, and then K self-increment. This ensures that the first three times the value is slow and the subsequent value is fast.
This time someone will ask, that example is a total of two, one is 400ms, one is 200ms, why the first three times is not 400+200 total 600ms, but the interval only 400ms it?
Let me explain, because the code runs to <-slow when it is blocking state, there is no value in the channel, it is necessary to store the value of the device every 400ms to slow, in order to continue to run. And <-limiter is also a blocking state, also need to pass the value of the device. But don't forget, limiter is 200ms, before slow pass value, limiter has already deposited the value. So after the IF judgment statement, the limiter does not have to wait for the value, direct fetch on the line. In this case, after the IF condition is executed, the <-limiter execution is instantaneous, without waiting for 200ms.
The above is the go language of the speed limit of some thinking and transformation, in the actual work, there should be a more perfect solution, looking forward to future improvements.
005_ on the speed limit in the Go language