Viene spesso utilizzato per implementare i moduli di sicurezza, come i firewall per le applicazioni web e le protezioni dai bot. Durante la messa in opera le sue performance possono essere monitorate attraverso l’exporter prometheus: questo permette di misurare continuamente la reale latenza media introdotta nello spoe backend dal meccanismo di protezione.
Il protocollo di stream processing offload è molto efficiente e i risultati ottenuti da questa misurazione possono sembrare impossibili, per alcuni aspetti sono contro-intuitivi.
Il blind testing è una metodologia di valutazione delle prestazioni in cui i soggetti coinvolti nel test non sono a conoscenza di alcuni dettagli critici dell’esperimento. Nel contesto dei benchmark di performance, questo approccio elimina i pregiudizi consci e inconsci, garantisce risultati più oggettivi e riduce l’influenza delle aspettative sui risultati.
Il test viene condotto senza che i partecipanti sappiano quali sono i funzionamenti interni del sistema che stanno effettivamente testando, assicurando così una valutazione imparziale delle performance.
In questo caso specifico i risultati possono essere utili per confermare o smentire i valori recuperati di latenza recuperati tramite le misurazioni effettuate con l’exporter Prometheus.
haproxy.cfg
frontend myproxy
mode http
bind 127.0.0.1:12346
# dichiarazione del filtro e del suo file di configurazione
filter spoe engine ip-reputation config iprep.conf
# rifiuta la connessione se la reputazione dell'IP è inferiore a 20
tcp-request content reject if { var(sess.iprep.ip_score) -m int lt 20 }
default_backend webservers
# usuale backend per i server web
backend webservers
mode http
stats uri /stats
stats refresh 10s
server web1 127.0.0.1:12347 check
# backend utilizzato dallo SPOE ip-reputation
backend agents
mode tcp
balance roundrobin
timeout connect 10s
timeout server 10s
option spop-check
server agent 127.0.0.1:12345 check
iprep.conf
[ip-reputation]
spoe-agent iprep-agent
messages check-client-ip
option var-prefix iprep
timeout hello 2m
timeout idle 2m
timeout processing 1m
use-backend agents
log global
spoe-message check-client-ip
args ip=src
event on-client-session
main.go
package main
import (
"log"
"net"
"net/http"
"time"
"github.com/negasus/haproxy-spoe-go/action"
"github.com/negasus/haproxy-spoe-go/agent"
"github.com/negasus/haproxy-spoe-go/logger"
"github.com/negasus/haproxy-spoe-go/request"
)
var (
latency int64 // artificially add latency to the spoa handler
testLatencies = []int64{0, 1, 10, 100, 1000}
testRequests = []uint{10, 100, 1000}
)
func main() {
log.SetFlags(0)
go func() {
listener, err := net.Listen("tcp4", "127.0.0.1:12345")
if err != nil {
log.Fatalf("error listen: %s\n", err.Error())
}
a := agent.New(handler, logger.NewDefaultLog())
if err := a.Serve(listener); err != nil {
log.Printf("error agent serve: %+v\n", err)
}
}()
go func() {
srv := &http.Server{
Addr: "127.0.0.1:12347",
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
}),
}
if err := srv.ListenAndServe(); err != nil {
log.Fatalf("error starting the webserver: %s\n", err.Error())
}
}()
time.Sleep(time.Minute)
for _, testLatency := range testLatencies {
latency = testLatency
avgLatency := float64(0)
for _, testRequest := range testRequests {
for i := uint(0); i < testRequest; i++ {
start := time.Now()
resp, err := http.Get("http://127.0.0.1:12346")
if err != nil {
log.Fatalf("error making request: %s\n", err.Error())
} else {
defer resp.Body.Close()
elapsed := time.Since(start)
avgLatency += float64(elapsed.Milliseconds())
}
}
avgLatency /= float64(testRequest)
log.Printf("Average latency for %d requests with latency %d ms: %f ms\n", testRequest, latency, avgLatency)
time.Sleep(10 * time.Second)
}
}
}
func handler(req *request.Request) {
mes, err := req.Messages.GetByIndex(0)
if err != nil {
log.Fatalf("no message was found: %s\n", err.Error())
return
}
ipValue, ok := mes.KV.Get("ip")
if !ok {
log.Fatalf("var 'ip' not found in message")
return
}
_, ok = ipValue.(net.IP)
if !ok {
log.Fatalf("var 'ip' has wrong type. expect IP addr")
return
}
time.Sleep(time.Duration(latency) * time.Millisecond)
req.Actions.SetVar(action.ScopeSession, "ip_score", 50)
}
Lo scopo di questo codice è valutare le prestazioni di un agente HAProxy SPOE misurando la latenza media introdotta dall’agente in diverse condizioni di tempi di risposta dell’agente e carico di richieste.
Ogni aspetto della struttura del codice è importante:
handler
dell’agente e misurando i tempi di risposta end-to-end.latency
e la funzione time.Sleep
nell’handler
vengono utilizzate per simulare i diversi tempi di risposta che un agente SPOE reale potrebbe impiegare per eseguire attività come controlli di sicurezza, trasformazioni dei dati, altra logica personalizzata, trasporto su rete.log.Printf
producono la latenza media per ogni combinazione di delay artificiale introdotto e carico di richieste, permettendo l’analisi e il confronto del risultato.L’esecuzione del test sull’interfaccia di loopback (127.0.0.1
) è cruciale per isolare l’ambiente di test, per minimizzare l’impatto di fattori di rete esterni sulle misurazioni della latenza, per garantire che i risultati del test siano più coerenti e riproducibili.
set xlabel ‘Response Time’ / set ylabel ‘Average Latency’ / set logscale x
plot ‘plot.csv’ using 1:2 with linespoints title ‘10 Requests’, ‘plot.csv’ using 1:3 with linespoints title ‘100 Requests’, ‘plot.csv’ using 1:4 with linespoints title ‘1000 Requests’
0, 0.400000, 0.024000, 0.003024
1, 1.400000, 1.804000, 1.889804
10, 11.900000, 11.936869, 11.936869
100, 102.900000, 103.599000, 102.555599
1000, 1004.300000, 1013.343000, 1003.964343