|
Omezování rychlosti (Rate limiting) je důležitý mechanismus pro kontrolu využívání zdrojů a udržování kvality služeb. Go elegantně podporuje omezování rychlostí pomocí gorutin, kanálů a opakujících časovaců tickers. |
|
package main
|
|
import "time"
import "fmt"
|
|
func main() {
|
|
|
Nejprve se podíváme na základní omezení rychlosti. Předpokládejme že chceme omezit správu našich příchozích požadavků. Budeme obsluhovat tyto požadavky z kanálu se jménem requests. |
requests := make(chan int, 5)
for i := 1; i <= 5; i++ {
requests <- i
}
close(requests)
|
|
Tento |
limiter := time.Tick(200 * time.Millisecond)
|
|
Pomocí blokování na příjmu z kanálu |
for req := range requests {
<-limiter
fmt.Println("požadavek", req, time.Now())
}
|
|
Možná že chceme dovolit krátké dávky pořadavků v
našem schématu omezování rychlosti. zatímco
zachováváme celkový limit rychlosti.
To můžeme udlělat pomocí kanálu s vyrovnávací
pamětí. Tento kanál |
burstyLimiter := make(chan time.Time, 3)
|
|
Naplníme kanál pro demonstraci dovolené velikosti dávky. |
for i := 0; i < 3; i++ {
burstyLimiter <- time.Now()
}
|
|
Kažých 200 milisekund se pokusíme přidat novou
hodnotu do kanálu |
go func() {
for t := range time.Tick(200 * time.Millisecond) {
burstyLimiter <- t
}
}()
|
|
Nyní simulujeme 5 dalších příchozích požadavků.
První tři z nich využijí dávkovou schopnost
|
burstyRequests := make(chan int, 5)
for i := 1; i <= 5; i++ {
burstyRequests <- i
}
close(burstyRequests)
for req := range burstyRequests {
<-burstyLimiter
fmt.Println("požadavek", req, time.Now())
}
}
|
|
Po spuštětní našeho programu uvidíme první dávku požadavků zpracovanou jednou za ~200 milisekund, jak jsme chtěli. |
$ go run rate-limiting.go
požadavek 1 2009-11-10 23:00:00.2 +0000 UTC m=+0.200000001
požadavek 2 2009-11-10 23:00:00.4 +0000 UTC m=+0.400000001
požadavek 3 2009-11-10 23:00:00.6 +0000 UTC m=+0.600000001
požadavek 4 2009-11-10 23:00:00.8 +0000 UTC m=+0.800000001
požadavek 5 2009-11-10 23:00:01 +0000 UTC m=+1.000000001
|
|
Ve druhé dávce požadavků obsloužíme první 3 okamžitě díky velikosti dávky v limitování rychlosti, potom obsloužíme zbývající 2 s přibližnou prodlevou ~200ms na každý. |
požadavek 1 2009-11-10 23:00:01 +0000 UTC m=+1.000000001
požadavek 2 2009-11-10 23:00:01 +0000 UTC m=+1.000000001
požadavek 3 2009-11-10 23:00:01 +0000 UTC m=+1.000000001
požadavek 4 2009-11-10 23:00:01.2 +0000 UTC m=+1.200000001
požadavek 5 2009-11-10 23:00:01.4 +0000 UTC m=+1.400000001
|
Další příklad: Atomické countery.