NFsec Logo

Stan TCP – TIME_WAIT

02/09/2010 w Administracja, Debug 1 komentarz.  (artykuł nr 278, ilość słów: 382)

Jednym ze stanów połączenia protokołu TCP jest TIME_WAIT. Jest to stan, w którym następuje oczekiwanie w celu upewnienia się, że druga strona otrzymała potwierdzenie rozłączenia. Zgodnie z dokumentem RFC 793 połączenie w takim stanie może być najdłużej przez 4 minuty. W systemie Linux standardową wartością dla tego stanu jest 60 sekund. Podczas oczekiwania w stanie TIME_WAIT ponowne nawiązanie połączenia z klientem (retransmisja) kosztuje znacznie mniej niż nawiązanie nowego połączenia. Jednak utrzymywanie bardzo wielu połączeń w tym stanie wpływa niekorzystnie na wydajność serwera.

Poprzez redukcję czasu oczekiwania dla tego stanu, protokół TCP może znacznie szybciej zwalniać zamknięte połączenia tym samym szybciej udostępniając zasoby na nowe połączenia. Na wielu stronach dostępnych w Internecie podawana jest informacja, że poprzez zmianę parametru:

echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

lub dodanie wpisu do /etc/sysctl.conf:

net.ipv4.tcp_fin_timeout = 30

można zredukować czas stanu TIME_WAIT w jakim pozostaje połączenie. Nic bardziej mylnego. Ustawienie to odnosi się do stanu FIN-WAIT, a nie TIME_WAIT. Czas dla stanu TIME_WAIT jest na stałe ustawiony w źródłach jądra Linux (chociaż były propozycje ustawienia go jako zmiennej):

root@stardust:~# cat /usr/src/linux/include/net/tcp.h | grep TCP_TIMEWAIT_LEN
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT

a jego zmiana wiąże się z rekompilacją jądra. Oprócz dość czasochłonnego skrócenia czasu dla oczekiwania w tym stanie możemy dodatkowo wykorzystać mechanizm “recyklingu” tych gniazd:

echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

lub dodać wpis do /etc/sysctl.conf:

net.ipv4.tcp_tw_recycle = 1

Z opcją tą należy obchodzić się dość ostrożnie, ponieważ w niektórych warunkach szybkie odzyskiwanie gniazd TIME_WAIT może spowodować problemy – szczególnie w warunkach, w których występuje równoważenie obciążenia (ang. load balancing) lub poprawna praca mimo awarii (ang. failover). Znane są również problemy przerywania połączeń użytkowników znajdujących się za mechanizmem NAT. Znacznie bezpieczniejsze z punktu widzenia protokołu jest wykorzystanie techniki ponownego użycia gniazd TIME_WAIT (działa tylko od strony klienta):

echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

lub dodać wpis do /etc/sysctl.conf:

net.ipv4.tcp_tw_reuse = 1

Jest to bardzo przydatne ustawienie szczególnie w warunkach, w których następuje otwieranie licznych, krótkich połączeń pozostawianych w stanie TIME_WAIT – np. serwery WWW. Ponowne wykorzystywanie tego rodzaju stanów dla nowych połączeń może bardzo efektywnie zmniejszyć obciążenie serwera. Wszystkie połączenia w stanie TIME_WAIT możemy wyświetlić za pomocą polecenia: netstat -tapn | grep TIME_WAIT lub ss -tan | grep TIME-WAIT.

Więcej informacji: Protokół TCP, man netstat, Kształtowanie Ruchu i Zaawansowany Routing

Kategorie K a t e g o r i e : Administracja, Debug

Tagi T a g i : , , , , , , , , ,

1 komentarz.

  1. Po bardzo dokładnej analizie okazuje się stan TIME_WAIT bardziej przyjacielem niż wrogiem systemu oraz istnieje wiele innych sposobów (np. zwiększenie zakresu portów) na poradzenie sobie z bardzo dużą ilością gniazd w tym stanie.