Il Rate limiting è un’importante tecnica per controllare l’uso delle risorse e mantenere un’alta qualità di servizio. Go supporta elegantemente il rate limiting tramite le goroutine, i channel e i ticker. |
|
package main
|
|
import "time"
import "fmt"
|
|
func main() {
|
|
Come prima cosa vedremo un semplice esempio di rate limiting. Supponiamo di dover limitare il numero di richieste (per esempio in un server HTTP). Utilizzeremo un channel per mimare l’entrata delle richieste. |
richieste := make(chan int, 5)
for i := 1; i <= 5; i++ {
richieste <- i
}
close(richieste)
|
Questo channel |
limitatore := time.Tick(time.Millisecond * 200)
|
Bloccando l’esecuzione su una ricezione da
|
for ric := range richieste {
<-limitatore
fmt.Println("richiesta", ric, time.Now())
}
|
Potremmo aver bisogno di sostenere brevi
“raffiche” di richieste, mantenendo comunque
il rate limiting. Possiamo fare ciò mettendo
bufferizzando il nostro channel. Questo channel
|
limitatoreARaffica := make(chan time.Time, 3)
|
Riempiamo il channel per dire che già dall’inizio possiamo prendere in carico 3 richieste. |
for i := 0; i < 3; i++ {
limitatoreARaffica <- time.Now()
}
|
Ogni 200 millisecondi proveremo ad inviare un
nuovo valore al |
go func() {
for t := range time.Tick(time.Millisecond * 200) {
limitatoreARaffica <- t
}
}()
|
Ora simuleremo 5 richieste al nostro limitatore. Le prime tre potranno godere della capacità del limitatore di eseguire richieste a raffica. |
richiesteARaffica := make(chan int, 5)
for i := 1; i <= 5; i++ {
richiesteARaffica <- i
}
close(richiesteARaffica)
for ric := range richiesteARaffica {
<-limitatoreARaffica
fmt.Println("richiesta", ric, time.Now())
}
}
|
Eseguendo il nostro programma vedremo il gruppo di richieste che verranno gestite ognuna ogni 200 millisecondi. |
$ go run rate-limiting.go
richiesta 1 2016-04-17 19:05:37.736132953 +0200 CEST
richiesta 2 2016-04-17 19:05:37.936138961 +0200 CEST
richiesta 3 2016-04-17 19:05:38.136209943 +0200 CEST
richiesta 4 2016-04-17 19:05:38.336145582 +0200 CEST
richiesta 5 2016-04-17 19:05:38.536120745 +0200 CEST
|
Invece, per il nostro secondo gruppo di richieste vedremo che le prime tre vengono eseguite all’istante, mentre le altre 2 a distanza di 200 millisecondi l’una dall’altra. |
richiesta 1 2016-04-17 19:05:38.536251527 +0200 CEST
richiesta 2 2016-04-17 19:05:38.536266185 +0200 CEST
richiesta 3 2016-04-17 19:05:38.536277665 +0200 CEST
richiesta 4 2016-04-17 19:05:38.736385724 +0200 CEST
richiesta 5 2016-04-17 19:05:38.936385957 +0200 CEST
|
Prossimo esempio: Contatori Atomici.