Reverse Proxy

Benchmarki

Wyniki benchmarków gorących ścieżek, profilowanie i testy race. Co jest allocation-free i gdzie naprawdę idzie czas.

Wyniki#

Go 1.27, linux/amd64, 2 vCPU sandbox:

Benchmarkns/opB/opallocs/op
RoundRobinNext (parallel)4700
WeightedRoundRobinNext (parallel)5200
LeastConnectionsNext (parallel)8500
BackendState (parallel)3900
MemoryAllowSingleKey (parallel)18900
MemoryAllowManyKeys (parallel)19720
ProxyServeHTTP (end-to-end hop)61 µs40 KB93

Wnioski z profilowania#

Koszt requestu dominowany jest przez internale net/http: klonowanie requestu, parsowanie nagłówków MIME, syscalle socketowe. Ścieżki load balancera, breakera i limitera są allocation-free.

Pozostałe alokacje pochodzą z samego httputil.ReverseProxy i nie są warte reimplementacji — to sprawdzony, utrzymywany kod standardowej biblioteki.

Liczby per maszyna

Wyniki zależą od sprzętu i wersji Go. Uruchom benchmarki na swojej maszynie przed wyciąganiem wniosków — wartości powyżej to punkt odniesienia, nie obietnica.

Uruchamianie#

bash
go vet ./...
go test -race -count=1 ./...

go test -run '^$' -bench=. -benchmem ./...

go test -run '^$' -bench=BenchmarkProxyServeHTTPParallel \
  -cpuprofile=cpu.out -memprofile=mem.out ./internal/proxy/

Analiza profili#

bash
go tool pprof -http=:8081 cpu.out
go tool pprof -http=:8082 mem.out

Szukaj:

  • alokacji w balancer, breaker, limiter — powinno być zero,
  • czasu w net/http — to normalne i oczekiwane,
  • lock contention w BackendState — atomics, nie mutexy.

Testy integracyjne#

internal/app pokrywa na httptest serwerach in-memory:

  • proxying i failover,
  • retry i odpowiedzi błędów backendów,
  • rate limiting,
  • admin authentication i traffic control,
  • health-check recovery,
  • endpointy operacyjne.
bash
go test -race -count=1 ./internal/app/

CI#

GitHub Actions uruchamia:

  • gofmt,
  • go vet,
  • testy z -race,
  • build,
  • Docker build,
  • benchmarki.

Release jest automatyzowany dla tagów.