GH GambleHub

Puli połączeń i opóźnienia

Puli połączeń i opóźnienia

1) Dlaczego baseny są potrzebne

Połączenia są drogie (uściski dłoni TCP/TLS, uwierzytelnianie, rozgrzewka). Pula umożliwia:
  • Ponowne użycie gotowych połączeń (utrzymać przy życiu) → poniżej TTFB.
  • Kontrolować współistnienie i nadać odwrotne ciśnienie zamiast lawiny rekolekcji.
  • Zmniejszyć ogony p95/p99 ze względu na prawidłowy rozmiar i harmonogram.

Kluczowe ryzyko: kolejki oczekujących w basenie, blokowanie głowy linii, zawartość połączeń i burza rekolekcji.

2) Podstawa matematyczna: Jak policzyć rozmiar puli

Używamy prawa Little'a: 'L = α × W'. W przypadku puli oznacza to:
  • „na” oznacza średni strumień żądań (RPS).
  • „W” oznacza średnie połączenie zajęte na żądanie (czas obsługi, w tym opóźnienie sieci i obsługa zdalna).
  • Minimalny rozmiar puli to 'N _ min, I × W'.
  • Dodaj margines dla zmian i p99: zagłówek 20-50%.
  • Przykład: 300 RPS, średni czas wstrzymania 40 ms → 'N _ min = 300 × 0. 04 = 12`. Z marginesem 50%, 18 połączeń są →.

Jeśli ogony są duże: rozważyć 'W _ p95' lub 'W _ p99' dla ścieżek krytycznych - baseny rosną.

3) Ogólne zasady projektowania

1. Krótka ścieżka danych: ponowne użycie (utrzymanie przy życiu, HTTP/2/3 multipleksowanie).
2. Ograniczenie paralelizmu: lepiej szybko odmówić (429/503) niż usmażyć plecy.
3. Timeouts> rekolekcje: Ustaw małe czasowe i rzadkie rekolekcje jitter.
4. Kolejki klientów są krótsze niż kolejki serwerów (szybka awaria).
5. Backpressure: gdy pula jest pełna - natychmiast NACK/błąd/collbeck „później”.
6. Izolacja basenów według celów: DB, pamięć podręczna, zewnętrzny PSP - ich granice.

4) HTTP/1. 1 vs HTTP/2/3, utrzymać przy życiu

HTTP/1. 1: jedno żądanie połączenia na raz (praktycznie); potrzebuje puli z wieloma połączeniami na hosta.
HTTP/2: multipleksowanie strumienia w jednym TCP; mniej połączeń, ale blokowanie HOL na TCP jest możliwe, gdy pakiety są tracone.
HTTP/3 (QUIC): strumieniowanie niezależności od UDP - mniej problemów z HOL, szybsze pierwsze bajty.

Ustawienia, które pomagają:
  • utrzymać żywy czas 30-90 lat (według profilu), limit wniosków o podłączenie (wdzięczny recykling).
  • Wstępne ogrzewanie (preconnect) na początku pracy.
  • Ograniczyć maksymalne przepływy na HTTP/2 (np. 100-200).
NGINX (upstream keep alive):
nginx upstream backend {
server app-1:8080;
server app-2:8080;
keepalive 512;
keepalive_requests 1000;
keepalive_timeout 60s;
}
proxy_http_version 1. 1;
proxy_set_header Connection "";
Wysłannik (pula HTTP/2):
yaml http2_protocol_options:
max_concurrent_streams: 200 common_http_protocol_options:
idle_timeout: 60s max_connection_duration: 3600s

5) Baseny DB: PgBouncer, HikariCP, sterowniki

Celem jest ograniczenie konkurencyjnych transakcji i utrzymywanie krótkich łączy.

5. 1 PgBouncer (PostgreSQL)

Tryby: 'session '/' transaction '/' statement'. Dla API - częściej transakcja.
Ważnymi parametrami są 'pool _ size', 'min _ pool _ size', 'reserve _ pool _ size', 'server _ idle _ timeout', 'query _ wait _ timeout'.

ini
[databases]
appdb = host=pg-primary port=5432 dbname=appdb

[pgbouncer]
pool_mode = transaction max_client_conn = 5000 default_pool_size = 100 min_pool_size = 20 reserve_pool_size = 20 query_wait_timeout = 500ms server_idle_timeout = 60 server_reset_query = DISCARD ALL

5. 2 HikariCP (Jawa)

Małe, szybkie połączenia, trudne czasy.

properties dataSourceClassName=org. postgresql. ds. PGSimpleDataSource maximumPoolSize=30 minimumIdle=5 connectionTimeout=250 validationTimeout=200 idleTimeout=30000 maxLifetime=1800000 leakDetectionThreshold=5000
Zasady:
  • „maximumPoolSize z RPS × W × zagłówkiem”.
  • "łączy Timeout 'hundreds milisekund, nie sekund.
  • Włącz wykrywanie przecieków.

5. 3 Go/Node/Python - przykłady

Idź http. Klient (ponowne użycie + timeouts):
go tr:= &http. Transport{
MaxIdleConns:    512,
MaxIdleConnsPerHost: 128,
IdleConnTimeout:   60 time. Second,
TLSHandshakeTimeout: 2 time. Second,
}
c:= &http. Client{
Transport: tr,
Timeout:  2 time. Second ,//general
}
Węzeł. js utrzymać czynnik żywy:
js const http = require('http');
const agent = new http. Agent({ keepAlive: true, maxSockets: 200, maxFreeSockets: 64, timeout: 60000 });
Psycopg/SQLAlchemy (Python):
python engine = create_engine(
url, pool_size=30, max_overflow=10, pool_recycle=1800, pool_pre_ping=True, pool_timeout=0. 25
)

6) Kolejki oczekujące i opóźnienia ogona

Ogony występują, gdy:
  • Pula jest mniejsza niż '× W' → Kolejka połączeń rośnie.
  • Nierówność obciążenia (wybuchy) bez bufora i ograniczeń.
  • Długie żądania podejmują połączenie i tworzą HOL.
Środki zaradcze:
  • Oddzielne puli według typu żądania (szybki/wolny).
  • Wdrożenie harmonogramu po stronie klienta. W przypadku wygaśnięcia - szybki NACK.
  • Wykrywanie i łamanie obwodów na trasach (wysłannik, HAProxy).
  • Kontyngenty na „ciężkie” trasy, oddzielna pula sprawozdań/wywozu.
Wyłącznik wysłannika (przykład):
yaml circuit_breakers:
thresholds:
- priority: DEFAULT max_connections: 200 max_pending_requests: 100 max_requests: 1000 max_retries: 2

7) Terminy i rekolekcje (prawidłowa kolejność)

1. Podłącz czas (krótki: 50-250 ms wewnątrz DC).
2. TLS handshake timeout (500-1000 ms вна DC).
3. Żądanie/Przeczytaj czas (bliżej trasy SLO).
4. Retry: maksymalnie 1 czas, tylko dla metod idempotent; jitter + backoff.
5. Budżet retrospektywny: globalny limit procentowy RPS (na przykład ≤ 10%).

8) Utrzymaj się przy życiu, Nagle, protokoły

Wyłączyć Nagle (TCP_NODELAY) dla małych komunikatów RPC.
Włączanie HTTP w miarę możliwości.
Uważaj na TIME_WAIT - tune 'reuse '/' recycle' tylko wtedy, gdy rozumiesz konsekwencje; lepsze - ponowne użycie połączeń, a nie dostrajanie jądra.
TLS - Użyj wznowienia sesji i ALPN.

9) OS/Kernel tuning (z ostrożnością)

'net. rdzeń. somaxconn', 'net. ipv4. ip_local_port_range', "net. ipv4. tcp_fin_timeout'.
Deskryptory: 'nofile' ≥ 64 k na proces proxy.
Saldo IRQ, GRO/LRO - według profilu ruchu.
Priorytet - profil; dostrajanie bez metryk jest często szkodliwe.

10) Obserwowalność: co mierzyć

Wykorzystanie puli: zajęty/razem, połączenie p50/p95 w toku.
Żądania podczas lotu i ich czas wstrzymania (przekroje trasy).
Budżet błędu retrospektywnego: odsetek powtórzeń.
Połączenie churn Utwórz/Zamknij na sekundę.
TCP/TLS: SYN RTT, uściski dłoni, ponowne użycie sesji.
МлКА: aktywne połączenia, czekanie, długie transakcje, zamki.

Мрабика: „RPS vs pool wait”, „hold-time distribution”, „reuse ratio”, „circuit trips”.

11) Przepisy przypadku

11. 1 brama API → backend

HTTP/2 do backendów, 'max _ concurrent _ streams = 200'.
Basen 20-40 połączeń na usługę na węzeł bramy.
Timeouts: connect 100ms, per-try 300-500ms, shared 1-2s, 1 retry with jitter.

11. 2 PostgreSQL → usługa za pośrednictwem PgBouncer

'pool _ mode = transaction', 'default _ pool _ size' według wzoru (RPS × W × 1. 3).
W przypadku transakcji krótkoterminowych ≤ 250 ms (<100 ms).
Ciężkie zgłoszenia - oddzielna pula/replika.

11. 3 gRPC wewnętrzne

Jeden kanał (HTTP/2) na hosta docelowego z limitem gwintu 100-200.
Termin na RPC na trasie SLO, przekaźnik tylko idempotent.
Długie próbkowanie RPC i metryki czasowe.

12) Lista kontrolna realizacji (0-30 dni)

0-7 dni

Pomiar „W” (czas wstrzymania) na kluczowych trasach/klientach.
Oblicz 'N _ min = na × W' i dodaj 30-50% zagłówka.
Włącz utrzymać żywe i krótkie timeouts połączenia.

8-20 dni

Oddzielne puli (szybkie/wolne/zewnętrzne).
Wyłączniki typu i budżety przekaźnikowe.
Dodaj deski rozdzielcze: basen czekać p95, stosunek ponownego użycia, w locie.

21-30 dni

Ładunek działa z wybuchami, test chaosu „upadek pleców”.
Optymalizacja ogona: izolacja ciężkich tras, lokalnych buforów.
Wzory dokumentów i limity w książce startowej 'ax.

13) Anty-wzory

Rozmiar basenu „losowo” i bez zagłówka.
Duży czas oczekiwania połączenia → długie ogony zamiast szybkich awarii.
Wiele wycofuje się bez jittera i idempotencji → burza.
Jedna wspólna pula dla wszystkich typów zapytań.
Długie transakcje zachować połączenie (DB) → głód reszty.
Niepełnosprawni utrzymać przy życiu lub zbyt mały bezczynność → ograniczenia churn i wzrost TTFB.

14) Wskaźniki zapadalności

Pool poczekać p95 w prod <10% całkowitej trasy p95.
Współczynnik ponownego użycia (> 90% dla wewnętrznego HTTP;> 80% dla zewnętrznych).
DB txn czas p95 <100-200 ms; odsetek transakcji długich <1%.
Szybkość ponownej próby <5% (i ≤ budżetu), błędy spowodowane terminami są stabilne i przewidywalne.
Udokumentowane rozliczenie puli dla wszystkich klientów krytycznych.

15) Wniosek

Efektywne łączenie połączeń to inżynieria kolejki + dyscyplina timeout. Zmierzyć 'W', obliczyć pulę 'α × W' z marginesem, włączyć keep-alive/HTTP2 +, oddzielne powolne ścieżki, zachować krótkie czasy i minimalne retras z jitter. Dodaj „pool wait vs latency” obserwowalność i wyłączniki - i dostajesz niski TTFB, kontrolowany ogon p99 i opór przepięcia bez przegrzania drzwi.

Contact

Skontaktuj się z nami

Napisz do nas w każdej sprawie — pytania, wsparcie, konsultacje.Zawsze jesteśmy gotowi pomóc!

Telegram
@Gamble_GC
Rozpocznij integrację

Email jest wymagany. Telegram lub WhatsApp są opcjonalne.

Twoje imię opcjonalne
Email opcjonalne
Temat opcjonalne
Wiadomość opcjonalne
Telegram opcjonalne
@
Jeśli podasz Telegram — odpowiemy także tam, oprócz emaila.
WhatsApp opcjonalne
Format: kod kraju i numer (np. +48XXXXXXXXX).

Klikając przycisk, wyrażasz zgodę na przetwarzanie swoich danych.