Przegląd
Lekki, produkcyjny reverse proxy w Go — load balancing, health checks, circuit breaker, rate limiting, metryki Prometheus i graceful shutdown.
Czym jest Reverse Proxy?#
Reverse Proxy to lekki, produkcyjny reverse proxy napisany w Go, zbudowany na net/http/httputil. Powstał jako projekt portfolio pod role Go Backend Developer, Platform Engineer i SRE — i jest kompletny: od konfiguracji po dashboard Grafany.
Najważniejsze możliwości#
Niezawodność#
- Trzy strategie load balancingu: Round Robin, Weighted Round Robin, Least Connections
- Aktywne health checks z konfigurowalnymi progami i natychmiastowym failover
- Graceful shutdown z drainowaniem requestów w locie
- Konfigurowalne timeouty serwera, dial, response header i idle
- Ścisła walidacja konfiguracji z czytelnymi błędami
- Thread-safe stan backendów (lock-free atomics)
Odporność#
- Circuit breaker per backend (closed → open → half-open) z fast-fail
- Retry policy z bezpiecznymi defaultami (tylko idempotentne requesty bez body)
- Ustrukturyzowane koperty błędów z request ID (
502/503/504)
Bezpieczeństwo#
- Admin API z bearer tokenem (constant-time comparison), fail-closed
- Bezpieczne wykrywanie IP klienta za trusted proxies (ochrona przed spoofingiem
X-Forwarded-For) - Stripowanie hop-by-hop headers, walidacja URL backendów
- Sekrety tylko przez zmienne środowiskowe
- Utwardzony obraz kontenera: non-root, read-only FS, dropped capabilities
Obserwowalność#
- Strukturalne logi
log/slog(JSON lub text) z request ID - Metryki Prometheus: requesty, latencja, błędy backendów, circuit breakery, rate limit
- Gotowy stack Prometheus + Grafana z dashboardem
Zarządzanie ruchem#
- Rate limiting per IP (token bucket) z ograniczoną pamięcią
- Opcjonalny Redis dla rozproszonego rate limitingu (atomowy Lua, fail-open)
Architektura#
Client
│
▼
Reverse Proxy (:8080)
├── Request ID → Access log/metrics → Rate limiter → Proxy handler
│ │
│ ┌───────────────────┐
│ │ Load balancer │
│ │ + circuit breaker │
│ └─────────┬─────────┘
├── Admin API (/admin/*, token) │
├── Prometheus (/metrics) ┌──────┴──────┐
└── Health (/healthz) ▼ ▼
Backend 1 Backend 2
(health checks + failover)
Każdy request przechodzi przez middleware chain (request ID, access log, rate limit), zanim handler wybierze zdrowy backend przez skonfigurowaną strategię. Nieudane próby są ponawiane zgodnie z retry policy; powtarzające się błędy otwierają circuit breaker, więc ruch failoveruje natychmiast, dopóki probe nie zakończy się sukcesem.
Stack#
- Go 1.26+
net/http+net/http/httputillog/sloggolang.org/x/time/rategithub.com/prometheus/client_golanggithub.com/redis/go-redis/v9gopkg.in/yaml.v3
Od czego zacząć?#
Docker Compose albo lokalny build w kilka minut.
Pełna referencja config.yaml z wartościami domyślnymi.
Trzy strategie i kiedy którą wybrać.
Docker, TLS, Redis i utwardzony kontener.
Struktura projektu#
reverse-proxy/
├── cmd/server/ # entrypoint (flagi, sygnały, wiring)
├── internal/
│ ├── admin/ # Admin API z tokenem
│ ├── app/ # wiring + testy integracyjne
│ ├── balancer/ # backendy + pickers (RR, WRR, least-conn)
│ ├── breaker/ # circuit breaker
│ ├── clientip/ # trusted-proxy client IP
│ ├── config/ # YAML + walidacja
│ ├── health/ # aktywne health checks
│ ├── httpx/ # request IDs, koperty błędów
│ ├── limiter/ # memory + Redis rate limiters
│ ├── logging/ # slog + access log
│ ├── metrics/ # Prometheus
│ ├── proxy/ # handler, retries, mapowanie błędów
│ └── server/ # HTTP(S) + graceful shutdown
├── config/ # przykładowe konfiguracje
├── deploy/ # demo backendy + monitoring
├── Dockerfile
└── docker-compose.yml