Un framework Go completo per implementare e testare algoritmi di rate limiting. Questo progetto fornisce implementazioni di esempio di varie strategie di limitazione del traffico insieme a strumenti client-server per la validazione e il benchmarking.
Questo progetto è composto da:
- Client di Test: Invia richieste a frequenze configurabili
- Server di Test: Funziona come server echo
- Esempi di Algoritmi: 4 diverse implementazioni di rate limiting
- Avviare il server:
go run server/main.go -protocol tcp -port 8080- In un altro terminale, avviare il client:
go run main.go -server localhost:8080 -rate 100 -duration 30s# Avviare il server TCP con log dettagliati
go run server/main.go -protocol tcp -port 8080 -verbose
# Test ad alta frequenza (1000 req/s, 10 connessioni)
go run main.go -rate 1000 -connections 10 -duration 60s
# Test con protocollo UDP
go run server/main.go -protocol udp -port 9090
go run main.go -protocol udp -server localhost:9090 -rate 500.
├── main.go # Client di test
├── server/
│ └── main.go # Server di test
└── sample/
├── token_bucket/ # Implementazione token bucket
├── fixed_window/ # Implementazione finestra fissa
├── sliding_window/ # Implementazione finestra scorrevole
└── concurrent/ # Implementazione thread-safe
Un client di test per rate limiting ad alte prestazioni.
Funzionalità:
- Supporto protocolli TCP/UDP
- Connessioni concorrenti multiple (solo TCP)
- Dimensione messaggi personalizzabile
- Visualizzazione statistiche in tempo reale
Opzioni della Linea di Comando:
-server string # Indirizzo del server (default "localhost:8080")
-protocol string # Protocollo: tcp o udp (default "tcp")
-rate int # Messaggi al secondo (default 100)
-duration duration # Durata del test (default 10s)
-connections int # Connessioni concorrenti, solo TCP (default 1)
-size int # Dimensione messaggio in byte (default 64)Esempio di Output:
Starting rate limit test client
Protocol: tcp
Server: localhost:8080
Rate: 1000 messages/second
Duration: 30s
Connections: 10
Message size: 64 bytes
--- Test Statistics ---
Duration: 30s
Messages sent: 30000
Messages succeeded: 29850
Messages failed: 150
Success rate: 99.50%
Actual rate: 1000.00 messages/second
Un server semplice che restituisce in echo i messaggi ricevuti.
Funzionalità:
- Supporto protocolli TCP/UDP
- Connessioni simultanee di più client
- Visualizzazione statistiche ogni 5 secondi
- Arresto graceful (Ctrl+C)
Opzioni della Linea di Comando:
-protocol string # Protocollo: tcp o udp (default "tcp")
-port int # Porta di ascolto (default 8080)
-verbose # Abilita log dettagliatiEsempio di Visualizzazione Statistiche:
[15:30:45] Received: 5023, Processed: 5023, Errors: 0, Rate: 1004.60 msg/s
[15:30:50] Received: 10089, Processed: 10089, Errors: 0, Rate: 1013.20 msg/s
Caratteristiche:
- Permette elaborazione a raffica
- Mantiene frequenza media permettendo picchi a breve termine
- Efficiente in memoria
Esempio di Utilizzo:
limiter := NewTokenBucket(100, 10) // Capacità 100, ricarica 10/secondo
if limiter.Allow() {
// Elabora richiesta
}Casi d'Uso:
- Limitazione rate API
- Controllo larghezza di banda
- Quando il traffico a raffica è accettabile
Caratteristiche:
- Implementazione semplice
- Utilizzo minimo di memoria
- Problemi ai bordi della finestra
Esempio di Utilizzo:
limiter := NewFixedWindowLimiter(1000, time.Minute) // 1000 richieste al minuto
if limiter.Allow() {
// Elabora richiesta
}Casi d'Uso:
- Quando serve un rate limiting semplice
- Le prestazioni sono prioritarie rispetto all'accuratezza
Caratteristiche:
- Rate limiting più accurato
- Risolve i problemi dei bordi della finestra fissa
- Utilizzo di memoria leggermente superiore
Esempio di Utilizzo:
limiter := NewSlidingWindowLimiter(100, time.Minute) // 100 richieste al minuto
if limiter.Allow() {
// Elabora richiesta
}Casi d'Uso:
- Quando è richiesto un rate limiting accurato
- L'equità è importante
Caratteristiche:
- Alte prestazioni con operazioni atomiche
- Supporto ambiente distribuito
- Esempio di middleware HTTP
Utilizzo del Middleware HTTP:
// Rate limiting per utente
userLimiters := &UserRateLimiters{
limiters: make(map[string]*ConcurrentTokenBucket),
limit: 100, // 100 richieste/minuto per utente
}
mux := http.NewServeMux()
mux.HandleFunc("/api/", handler)
// Applica middleware
http.ListenAndServe(":8080", RateLimitMiddleware(userLimiters)(mux))Confronto algoritmi (valori di riferimento):
| Algoritmo | Throughput | Utilizzo Memoria | Caratteristiche |
|---|---|---|---|
| Token Bucket | Alto | Basso | Supporto raffica |
| Finestra Fissa | Altissimo | Bassissimo | Semplice |
| Finestra Scorrevole | Medio | Medio | Accurato |
| Concorrente | Alto | Basso | Ottimizzato concorrenza |
# Test rate limiting server API (1000 req/s, 5 minuti)
go run main.go -server api.example.com:443 -rate 1000 -duration 5m -connections 50# Test aumento graduale del carico
for rate in 100 500 1000 2000 5000; do
echo "Testing rate: $rate req/s"
go run main.go -rate $rate -duration 1m
sleep 10
done# Misurazione larghezza di banda con messaggi grandi
go run main.go -size 1024 -rate 1000 -protocol udp-
Errore "Too many open files"
# Aumentare il limite dei file descriptor ulimit -n 65536
-
Errori di connessione ad alta frequenza
- Regolare il parametro
-connections - Verificare le dimensioni buffer lato server
- Regolare il parametro
-
Perdita pacchetti UDP
- Ridurre frequenza o dimensione messaggi
- Regolare dimensione buffer UDP del kernel
# Compilare client
go build -o rate-limit-client main.go
# Compilare server
go build -o rate-limit-server server/main.go# Eseguire test unitari
go test ./...
# Eseguire benchmark
go test -bench=. ./sample/...- Creare nuovo package nella directory
sample/ - Implementare interfaccia
RateLimiter:type RateLimiter interface { Allow() bool AllowN(n int) bool }
- Aggiungere test e benchmark
Licenza MIT
Le pull request sono benvenute. Per modifiche importanti, aprire prima una issue per discutere cosa si vorrebbe cambiare.