Reverse Proxy

Load balancing

Round Robin, Weighted Round Robin i Least Connections — jak działają, kiedy którą wybrać i jak wygląda failover.

Trzy strategie#

StrategiaJak wybieraKiedy stosować
round_robinPo kolei, cyklicznieJednorodne backendy, prosty default
weighted_round_robinProporcjonalnie do wagBackendy o różnej mocy
least_connectionsNajmniej requestów w locieDługie requesty, SSE, WebSockety
yaml
load_balancing:
  strategy: least_connections

Round Robin#

Klasyczna rotacja: backend 1 → backend 2 → backend 1… Wybór jest lock-free (atomics), więc narzut przy równoległych requestach jest minimalny — 47 ns/op, 0 alokacji w benchmarku równoległym.

yaml
backends:
  - url: http://10.0.0.1:8080
  - url: http://10.0.0.2:8080
  - url: http://10.0.0.3:8080

load_balancing:
  strategy: round_robin

Weighted Round Robin#

Każdy backend dostaje wagę 1–100. Ruch dzieli się proporcjonalnie:

yaml
backends:
  - url: http://big-server:8080
    weight: 3
  - url: http://small-server:8080
    weight: 1

load_balancing:
  strategy: weighted_round_robin

Przy wagach 3:1 duży serwer dostaje ~75% ruchu. Przydatne przy:

  • migracji ruchu na nowy klaster (stopniowe zwiększanie wagi),
  • backendach o różnej mocy (CPU/RAM),
  • canary release (waga 1 dla nowej wersji).

Przykład: canary release#

yaml
backends:
  - url: http://stable:8080
    weight: 9
  - url: http://canary:8080
    weight: 1

10% ruchu trafia do canary. Obserwujesz backend_errors_total{backend="http://canary:8080"} i zwiększasz wagę albo wycofujesz.

Least Connections#

Wybiera backend z najmniejszą liczbą requestów w locie (per-backend connection tracking):

yaml
load_balancing:
  strategy: least_connections

Najlepsza dla requestów o zmiennym czasie trwania — długie połączenia nie blokują rotacji, bo nowe requesty omijają zajęte backendy.

Failover#

Niezależnie od strategii, picker wybiera tylko backendy, które są:

  1. healthy — przeszły health checks,
  2. admin-up — nie wyłączone przez Admin API,
  3. closed/half-open — circuit breaker nie jest open.
text
request → picker → healthy & available backend
                 ↘ brak → 503 service_unavailable

Informacja

Stan backendu jest thread-safe przez lock-free atomics, a liczniki in-flight są per backend. Dzięki temu least_connections nie potrzebuje globalnego locka.

Nagłówki forwarded#

Do upstreamu trafiają:

  • X-Forwarded-For — IP klienta (z uwzględnieniem trusted proxies),
  • X-Forwarded-Host — oryginalny host,
  • X-Forwarded-Proto — oryginalny protokół.

Hop-by-hop headers (Connection, Keep-Alive, Transfer-Encoding…) są stripowane zgodnie z RFC.

Benchmark pickerów#

Benchmarkns/opB/opallocs/op
RoundRobinNext (parallel)4700
WeightedRoundRobinNext (parallel)5200
LeastConnectionsNext (parallel)8500

Wszystkie ścieżki wyboru są allocation-free. Szczegóły: Benchmarki.