Napisałem mały program, który współdziała z serwerem na określonym porcie. Program działa dobrze, ale:
Raz program zakończył się nieoczekiwanie i od tego czasu połączenie przez gniazdo jest pokazane w CLOSE_WAIT
stanie. Jeśli próbuję uruchomić program, zawiesza się i muszę wymusić jego zamknięcie, co gromadzi jeszcze więcej CLOSE_WAIT
połączeń gniazd.
Czy istnieje sposób na przepłukanie tych połączeń?
Odpowiedzi:
CLOSE_WAIT
oznacza, że twój program nadal działa i nie zamknął gniazda (a jądro czeka, aż to zrobi). Dodaj-p
do,netstat
aby uzyskać pid, a następnie zabij go mocniej (wSIGKILL
razie potrzeby za pomocą). To powinno pozbyć się twoichCLOSE_WAIT
gniazd. Możesz również użyć,ps
aby znaleźć pid.SO_REUSEADDR
dotyczy serwerów iTIME_WAIT
gniazd, więc nie ma tutaj zastosowania.źródło
Jak opisał Crist Clark .
źródło
close()
lubclosesocket()
, w zależności od używanej platformy.Mam również ten sam problem z najnowszym serwerem Tomcat (7.0.40). Nie reaguje raz na kilka dni.
Aby zobaczyć otwarte połączenia, możesz użyć:
Jak wspomniano w tym poście , możesz użyć,
/proc/sys/net/ipv4/tcp_keepalive_time
aby wyświetlić wartości. Wydaje się, że wartość jest wyrażona w sekundach i domyślnie wynosi 7200 (tj. 2 godziny).Aby je zmienić, musisz edytować
/etc/sysctl.conf
.źródło
Nawet jeśli zbyt wiele połączeń CLOSE_WAIT oznacza, że coś jest nie tak z twoim kodem w pierwszym i jest to akceptowane, nie jest dobrą praktyką.
Możesz sprawdzić: https://github.com/rghose/kill-close-wait-connections
To, co robi ten skrypt, to wysłanie ACK, na które czekało połączenie.
To właśnie zadziałało dla mnie.
źródło
Należy wspomnieć, że
Socket
instancja po stronie klienta i serwera musi być jawnie wywoływanaclose()
. Jeśliclose()
wywoła to również tylko jeden koniec , gniazdo pozostanie w stanie CLOSE_WAIT.źródło
Możesz wymusić zamknięcie gniazd za pomocą
ss
polecenia;ss
komenda jest narzędziem służącym do zrzutu statystyki gniazd i wyświetla informacje w podobny sposób (choć prostsze i szybsze) do netstat.Aby zabić dowolne gniazdo w stanie CLOSE_WAIT, uruchom to (jako root)
źródło
Warto również zauważyć, że jeśli program uruchomi nowy proces, ten proces może odziedziczyć wszystkie otwarte uchwyty. Nawet po zamknięciu własnego programu te odziedziczone uchwyty mogą nadal istnieć dzięki procesowi osieroconego dziecka. I niekoniecznie pojawiają się tak samo w netstacie. Ale mimo wszystko gniazdo będzie się kręcić w CLOSE_WAIT, gdy ten proces potomny będzie żył.
Miałem przypadek, w którym prowadziłem ADB. Sam ADB uruchamia proces serwera, jeśli nie jest jeszcze uruchomiony. To początkowo odziedziczyło wszystkie moje uchwyty, ale nie pojawiło się jako posiadanie żadnego z nich, gdy badałem (to samo dotyczyło zarówno systemu MacOS, jak i Windows - nie jestem pewien co do Linuksa).
źródło