TCP Keepalive określa, jak szybko serwer rozpoznaje i kończy nieaktywne sesje TCP - dźwignia kontroli, która ma bezpośredni wpływ na zużycie zasobów, opóźnienia i przestoje w hostingu. Dzięki odpowiednim wartościom bezczynności, interwału i sondy, redukuję martwe punkty połączeń, zapobiegam spadkom NAT i utrzymuję aplikacje internetowe w Konfiguracje hostingu niezawodny dostęp.
Punkty centralne
- ParametryUstawianie bezczynności, interwałów, sond w ukierunkowany sposób
- RozgraniczenieTCP Keepalive vs. HTTP Keep-Alive
- Na gniazdoZastąpienia dla każdej usługi/kubernetes pod
- Firewall/NATAktywne uwzględnianie limitów czasu bezczynności
- MonitoringPomiary, testy obciążeniowe, iteracyjne dostrajanie
Jak działa TCP Keepalive
Aktywuję Keepalive na poziomie gniazda lub systemu, tak aby stos wysyłał małe sondy w określonych odstępach czasu, gdy jest nieaktywny. Po ustawionym czasie oczekiwania (bezczynności), system wysyła pierwszą kontrolę; kolejne sondy następują w zdefiniowanych odstępach czasu, aż do osiągnięcia określonej liczby prób. Jeśli stacja zdalna pozostaje niema, kończę połączenie i zwracam deskryptory plików i bufory w folderze Jądro free. Logika wyraźnie różni się od retransmisji, ponieważ Keepalive sprawdza status aktywności przepływu, który w innym przypadku byłby uśpiony. Szczególnie w środowiskach hostingowych z wieloma jednoczesnymi sesjami, takie zachowanie zapobiega pełzającym wyciekom, które w przeciwnym razie często zauważałbym tylko przy wysokiej aktywności. Obciążenie czuć.
Dlaczego Keepalive liczy się w hostingu
Wadliwi klienci, sieci komórkowe i agresywne bramy NAT często pozostawiają po sobie ślady. Połączenia z zombie, które pozostają otwarte przez długi czas bez keepalive. Kosztuje to otwarte gniazda, pamięć RAM i procesor w procesach akceptujących, roboczych i proxy, co wydłuża czas odpowiedzi. Używam odpowiednich wartości, aby usunąć te martwe ciała na wczesnym etapie i utrzymać otwarte nasłuchiwacze, backendy i upstreamy. responsywny. Efekt jest szczególnie zauważalny podczas szczytowych obciążeń, ponieważ mniej martwych połączeń zapełnia kolejki. W związku z tym planuję Keepalive wraz z limitami czasu HTTP i TLS oraz zapewniam harmonijny Interakcja między wszystkimi warstwami.
Parametry sysctl: wartości praktyczne
Linux zapewnia bardzo długie wartości domyślne, które są używane w produktywnych aplikacjach Środowiska hostingowe rzadko pasuje. W przypadku serwerów internetowych zwykle ustawiam znacznie krótszy czas bezczynności, aby w odpowiednim czasie usunąć zawieszające się sesje. Odstępy między sondami utrzymuję na umiarkowanym poziomie, dzięki czemu szybko rozpoznaję awarie, ale nie zalewam sieci kontrolami. Równoważę liczbę sond między fałszywymi alarmami a czasem wykrywania; mniejsza liczba sond skraca czas do wykrycia awarii. Zasoby. W przypadku IPv6 zwracam uwagę na odpowiednie zmienne net.ipv6 i utrzymuję spójność obu protokołów.
| Parametry | Standard (Linux) | Rekomendacja dotycząca hostingu | Korzyści |
|---|---|---|---|
| tcp_keepalive_time | 7200s | 600-1800s | Gdy pierwsza próbka zostanie wysłana po bezczynności |
| tcp_keepalive_intvl | 75s | 10-60s | Odległość między poszczególnymi sondami |
| tcp_keepalive_probes | 9 | 3-6 | Maksymalna liczba nieudanych prób przed zamknięciem |
Ustawiam wartości bazowe w całym systemie i stosuję je na stałe za pośrednictwem sysctl, aby ponowne uruchomienie nie odrzuciło pracy strojenia. Ponadto dokumentuję wartości początkowe i mierzę wpływ na Wskaźniki błędów i opóźnienia. Pozwala mi to zachować równowagę między szybkim wykrywaniem a dodatkowym ruchem sieciowym. Często używam poniższych linii jako punktu wyjścia i dostosowuję je później do każdego obciążenia:
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 5
sysctl -p
Strojenie na gniazdo i platformę
Domyślne ustawienia globalne rzadko mi wystarczają; ustawiam je dla każdej usługi Na gniazdo-values, aby wrażliwe backendy działały dłużej, podczas gdy frontendy szybko się czyściły. W Pythonie, Go lub Javie ustawiam SO_KEEPALIVE i konkretne opcje TCP bezpośrednio na gnieździe. W Linuksie steruję poprzez TCP_KEEPIDLE, TCP_KEEPINTVL i TCP_KEEPCNT, podczas gdy Windows działa poprzez klucze rejestru (KeepAliveTime, KeepAliveInterval). W Kubernetes nadpisuję ustawienia na podstawie podów lub wdrożeń, aby traktować krótkotrwałe bramy API inaczej niż te długotrwałe Baza danych-proxy. W przypadku konfiguracji kontenerowych sprawdzam również tabele NAT hosta i wtyczki CNI, ponieważ nieaktywne przepływy są często usuwane wcześniej niż bym chciał.
Przykład # (Python, Linux)
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 30)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
HTTP Keep-Alive a TCP Keepalive
HTTP Keep-Alive utrzymuje połączenia otwarte dla wielu żądań, podczas gdy TCP Keepalive zapewnia czystą kontrolę żywotności na poziomie transportu. Oba mechanizmy uzupełniają się nawzajem, ale działają z różnymi celami i licznikami czasu. W HTTP/2 i HTTP/3 ramki PING częściowo przejmują rolę Keepalive, ale nadal dodatkowo zabezpieczam warstwę TCP. Ustawiam limit czasu HTTP zgodnie z widokiem aplikacji, podczas gdy ustawiam wartości TCP w oparciu o ekonomiczne wydanie Zasoby wyrównać. Jeśli chcesz dowiedzieć się więcej na temat strony HTTP, możesz znaleźć pomocny przewodnik na stronie HTTP Keep-Alive Timeout.
Dostrajanie limitu czasu w sieci: praktyczne
W przypadku klasycznych front-endów hostingowych, często pracuję z 300s bezczynności, 30-45s interwału i 4-6 sondami, aby szybko zakończyć nieaktywne sesje. Kolejki lean. Połączenia z bazami danych są bardziej cierpliwe, aby krótkie fazy zajętości nie powodowały niepotrzebnych rozłączeń. W bramach brzegowych lub API również skracam limity czasu, ponieważ istnieje wiele krótkotrwałych połączeń. Harmonizuję wartości z limitami czasu uzgadniania TLS, limitami czasu odczytu/zapisu i limitami czasu upstream, aby nie było sprzeczności na granicach warstw. Dla optymalizacji krok po kroku, kompaktowy Strojenie przepływu, którego używam w oknach konserwacyjnych.
Limity czasu bezczynności zapory sieciowej, NAT i chmury
Wiele firewalli i bramek NAT odcina nieaktywne przepływy po 300-900 sekundach, dlatego też Keepalive aby mój interwał był mniejszy niż ten. W przeciwnym razie aplikacja nie rozpozna zakończenia do następnego żądania i spowoduje niepotrzebne ponawianie prób. W load balancerach w chmurze sprawdzam parametry TCP lub bezczynności połączenia i porównuję je z wartościami sysctl i proxy. W konfiguracjach anycast lub multi-AZ sprawdzam, czy zmiany ścieżek prowadzą do pozornie martwych stacji zdalnych i specjalnie zwiększam liczbę próbek dla tych stref. Dokumentuję łańcuch klienta, proxy, firewalla i backendu, dzięki czemu mogę Przyczyny szybko spada.
Integracja z konfiguracją serwera WWW
Apache, Nginx i HAProxy organizują trwałość HTTP na poziomie aplikacji, podczas gdy system operacyjny TCP Keepalive dostarcza. W Apache włączam KeepAlive, ograniczam KeepAliveRequests i utrzymuję krótki KeepAliveTimeout, aby pracownicy byli szybko zwalniani. Używam Nginx z krótkim keepalive_timeout i umiarkowanym keepalive_requests dla wydajnego ponownego użycia. W HAProxy używam opcji gniazda, takich jak tcpka lub domyślnych ustawień systemowych, aby limity czasu transportu były zgodne z polityką proxy. Dla bardziej dogłębnych aspektów serwera sieciowego, sekcja Przewodnik dostrajania serwera WWW, które łączę z moimi dostosowaniami TCP.
Monitorowanie, testy i metryki
Mierzę efekt każdego dostosowania i nie polegam na Przeczucie. ss, netstat i lsof pokazują mi, ile połączeń ESTABLISHED, FIN_WAIT i TIME_WAIT jest obecnych i czy wycieki rosną. W metrykach monitoruję przerwania, RST, retransmisje, opóźnienia P95/P99 i długości kolejek; jeśli wartość osiągnie swoje limity, przechodzę konkretnie do Idle, Interval lub Probes. Używam syntetycznych testów obciążenia (np. ab, wrk, Locust) do symulacji rzeczywistych wzorców użytkowania i sprawdzam, czy strojenie spełnia docelowe metryki. Wdrażam zmiany etapami i porównuję serie czasowe przed globalny Rozmieść ustawienia domyślne na wszystkich hostach.
Obrazy błędów i rozwiązywanie problemów
Jeśli ustawię zbyt krótkie interwały, napompuję Ruch sieciowy i zwiększają ryzyko, że tymczasowe błędy zostaną zinterpretowane jako awarie. Jeśli jest zbyt mało sond, zamykam połączenia na żywo w powolnych sieciach, co użytkownicy napotykają jako sporadyczny komunikat o błędzie. Z drugiej strony zbyt długie czasy bezczynności prowadzą do przeciążenia gniazd i rosnących zaległości w akceptacji. Sprawdzam dzienniki pod kątem RST od klienta/serwera, ECONNRESET i ETIMEDOUT, aby rozpoznać kierunek. Jeśli dotyczy to głównie użytkowników mobilnych, dostosowuję sondy i interwały, ponieważ tam Martwe punkty a zaburzenia snu występują częściej.
Bezpieczne ustawienia domyślne dla różnych obciążeń roboczych
Zaczynam od konserwatywnych wartości, które są odpowiednie do produkcji i udoskonalam je po zmierzeniu Obciążenie pracą. Web API zwykle wymagają krótkich czasów bezczynności, bazy danych znacznie dłuższych. Proxy między strefami lub dostawcami korzystają z nieco większej liczby sond, aby poradzić sobie z trzepotaniem ścieżek. W przypadku aplikacji interaktywnych zmniejszam interwał i zwiększam liczbę sond, dzięki czemu szybciej zauważam błędy, ale nie zamykam ich przedwcześnie. Tabela daje mi kompaktową orientację, którą dostosowuję podczas pracy.
| Typ serwera | Bezczynność | Interwał | Próbki | Wskazówka |
|---|---|---|---|---|
| Webhosting frontend | 300-600s | 30-45s | 4-6 | Krótkie sesje, duża objętość |
| Brama API | 180-300s | 20-30s | 5-6 | Wiele faz bezczynności, szybkie czyszczenie |
| Pełnomocnik bazy danych | 900-1800s | 45-60s | 3-5 | Nawiązanie połączenia jest kosztowne, wykaż się cierpliwością |
| Kubernetes Pod | 600-900s | 30-45s | 4–5 | Synchronizacja z limitami czasu CNI/LB |
TCP_USER_TIMEOUT i retransmisja wsteczna
Oprócz Keepalive, w szczególności używam następujących połączeń do przesyłania danych TCP_USER_TIMEOUT, aby kontrolować, jak długo niepotwierdzone dane mogą pozostać w gnieździe, zanim połączenie zostanie aktywnie anulowane. Jest to szczególnie ważne w przypadku serwerów proxy i interfejsów API, które nie powinny zapętlać się przez wiele minut. W przeciwieństwie do Keepalive (który sprawdza aktywność podczas braku aktywności), TCP_USER_TIMEOUT działa, gdy dane przepływają, ale nie są zwracane żadne ACK - na przykład w przypadku błędów asymetrycznych. Ustawiłem na gniazdo nieco poniżej limitów czasu odczytu/zapisu aplikacji, aby poziom transportu nie czekał dłużej niż logika aplikacji w przypadku błędu.
Przykład # (Go, Linux) - Keepalive i TCP_USER_TIMEOUT
d := net.Dialer{
Timeout: 5 * time.Second,
KeepAlive: 30 * time.Second,
Control: func(network, address string, c syscall.RawConn) error {
var err error
c.Control(func(fd uintptr) {
// 20s niepotwierdzonych danych jest dozwolone
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 0x12, 20000) // TCP_USER_TIMEOUT
})
return err
},
}
conn, _ := d.Dial("tcp", "example:443")
Nie zapominam, że backoff TCP (rozszerzenie RTO) i ponawianie prób (tcp_retries2) również wpływają na zachowanie w przypadku utraty pakietów. Zbyt krótkie limity czasu użytkownika mogą prowadzić do utraty połączenia w trudnych sieciach, nawet jeśli stacja zdalna jest osiągalna. Dlatego ustawiam je ściśle tylko tam, gdzie celowo dążę do szybkiego wykrywania błędów (np. w proxy brzegowym).
IPv6 i funkcje systemu operacyjnego
Te same opcje dla każdego gniazda (TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT) mają zastosowanie dla IPv6. W zależności od wersji jądra, globalne wartości domyślne dla v4 i v6 mają zastosowanie razem; sprawdzam to za pomocą ss -o do rzeczywistych połączeń. W systemie Windows dostosowuję wartości domyślne za pośrednictwem rejestru (KeepAliveTime, KeepAliveInterval) i używam SIO_KEEPALIVE_VALS dla poszczególnych gniazd. Opcje są czasami nazywane inaczej na pochodnych BSD, ale semantyka pozostaje taka sama. Ważne jest, aby zweryfikować dla każdej platformy, czy nadpisania aplikacji faktycznie pokonują domyślne ustawienia systemowe i czy środowiska uruchomieniowe kontenerów prawidłowo dziedziczą przestrzenie nazw.
WebSockets, gRPC i streaming
Strumienie o długim czasie życia (WebSocket, gRPC, zdarzenia wysyłane przez serwer) korzystają szczególnie z dobrze dozowanych keepalives. Zaczynam od dwóch poziomów: Aplikacja wysyła okresowe pingi/PONGi (np. poziom WebSocket), podczas gdy warstwa TCP zabezpiecza się umiarkowanymi interwałami. Zapobiega to cichemu usuwaniu przepływów przez NAT. W przypadku klientów mobilnych zwiększam liczbę sond i wybieram dłuższe interwały, aby uwzględnić tryby oszczędzania energii. W przypadku gRPC/HTTP-2 koordynuję HTTP/2 PING z TCP Keepalive, aby nie sondować dwa razy zbyt agresywnie i nie wyczerpać baterii.
Tabele Conntrack, jądra i NAT
Na hostach z systemem Linux z aktywnym śledzeniem połączeń, zbyt krótkie nf_conntrack-timeout może prowadzić do wczesnego zerwania połączenia - nawet jeśli aplikacja myśli dłużej. Dlatego synchronizuję odpowiednie timery (np. nf_conntrack_tcp_timeout_established) z moimi interwałami keepalive, aby próbka dotarła bezpiecznie przed upływem terminu conntrack. Na węzłach z silnym NAT (NodePort, egress NAT) planuję rozmiar tabeli conntrack i hash buckets, aby uniknąć globalnej presji pod obciążeniem. Czyste ustawienia keepalive znacznie odciążają te tabele.
Przykład: Jednostki serwera proxy i serwera WWW
W HAProxy specjalnie aktywuję keepalive po stronie transportu i utrzymuję spójne limity czasu HTTP:
# Extract (HAProxy)
ustawienia domyślne
timeout client 60s
timeout server 60s
timeout connect 5s
option http-keep-alive
option tcpka # Włącz keepalive TCP (użyj domyślnych ustawień systemu operacyjnego)
backend app
server s1 10.0.0.10:8080 check inter 2s fall 3 rise 2
Myślę, że w Nginx ponowne użycie jest wydajne bez wiązania pracowników:
Fragment # (Nginx)
keepalive_timeout 30s;
keepalive_requests 1000;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
Upewniam się, że timeouty transportu i aplikacji logicznie do siebie pasują: Zapobieganie „martwym liniom“ jest zadaniem TCP/Keepalive, podczas gdy limity czasu aplikacji odwzorowują logikę biznesową i oczekiwania użytkowników.
Obserwowalność w praktyce
Weryfikuję działanie Keepalive na żywo na hoście:
- ss:
ss -tin 'sport = :443'pokazuje z-otimer (np. timer:(keepalive,30sec,0)), liczba ponawianych prób i wysyłanie/odbieranie Q. - tcpdumpFiltruję uśpione połączenie i widzę okresowe małe pakiety/ACK podczas faz bezczynności. To pozwala mi rozpoznać, czy sondy uruchamiają NAT w odpowiednim czasie.
- Dzienniki/MiernikiKoreluję szczyty RST/timeout ze zmianami idle/interval/probes. Spadek otwartych gniazd przy stałym obciążeniu wskazuje na udane porządkowanie.
W przypadku powtarzalnych testów symuluję awarie połączeń (np. wyłączenie interfejsu, iptables DROP) i obserwuję, jak szybko pracownicy/procesy zwalniają zasoby i czy ponowienia działają poprawnie.
Planowanie zasobów i wydajności
Keepalive jest tylko częścią równowagi. Upewniam się, że ulimit/nofile, fs.file-max, net.core.somaxconn oraz tcp_max_syn_backlog pasują do mojego numeru połączenia. Zbyt długie czasy bezczynności ukrywają tutaj deficyty, podczas gdy zbyt krótkie wartości zapewniają rzekomą stabilność, ale mocno uderzają w użytkowników. Planuję bufory (Recv-/Send-Q) i rezerwy FD ze scenariuszami obciążenia i mierzę, ile jednoczesnych bezczynnych połączeń mogą obsłużyć moje węzły, zanim ucierpią GC/Worker i kolejki akceptacji.
Kiedy nie polegam (tylko) na TCP Keepalive
W przypadku czysto wewnętrznego ruchu bez NAT, małej liczby połączeń i wyraźnych limitów czasu aplikacji, czasami rezygnuję z agresywnych keepalives i pozostawiam wykrywanie aplikacji (np. bicie serca na poziomie protokołu). I odwrotnie, w scenariuszach brzegowych i mobilnych priorytetem są krótkie interwały, kilka sond i dodanie HTTP/2 PING lub WebSocket ping. Ważne jest, aby nigdy nie dostrajać w izolacji: Wartości Keepalive muszą być zharmonizowane z próbami, wyłącznikami i strategiami backoff, tak abym mógł szybko wykrywać błędy, ale nie powodować trzepotania systemu.
Strategia wdrażania i walidacja
Wdrażam nowe ustawienia domyślne krok po kroku: Najpierw hosty Canary, potem AZ/strefa, a następnie cała flota. Porównania przed/po obejmują otwarte połączenia, procesor w trybie jądra, opóźnienia P95/P99, wskaźniki błędów i retransmisje. W Kubernetes testuję za pomocą adnotacji pod lub kontenerów init, które ustawiają przestrzenie nazw sysctl przed zmianą w całym węźle. W ten sposób minimalizuję ryzyko i zapewniam powtarzalne wyniki - a nie tylko postrzegane ulepszenia.
Krótkie podsumowanie
Dzięki dobrze przemyślanym TCP Ustawienia Keepalive, wcześnie usuwam nieaktywne połączenia, zmniejszam presję na zasoby i stabilizuję czasy odpowiedzi. Wybieram krótkie czasy bezczynności dla frontendu, dłuższe wartości dla stanowych backendów i zabezpieczam się umiarkowanymi interwałami i kilkoma lub średnimi sondami. Harmonizuję wartości z limitami czasu HTTP, TLS i proxy i utrzymuję je poniżej limitów bezczynności firewalla i NAT. Po każdym dostosowaniu mierzę zauważalny wpływ na opóźnienia, błędy i procesor, zamiast polegać na przeczuciu. W ten sposób osiągam niezawodny Platforma, która lepiej radzi sobie z obciążeniami szczytowymi i równomiernie obsługuje przepływy użytkowników.


