Uścisk dłoni WireGuard nadal się kończy, peer nadal pokazuje niedawny endpoint, a jednak nowa sesja SSH przez przekaźnik za nim wisi bez banera. Ta kombinacja wskazuje poza tunel, na proces, który przyjmuje gniazdo. Przekaźnik taki jak socat siedzi na ścieżce aplikacji z własnym budżetem deskryptorów, własnymi potomkami i własnymi odziedziczonymi limitami. Wędrówka poniżej zaczyna się przy kliencie i zatrzymuje na pierwszym elemencie, który nie może otworzyć kolejnego gniazda.

Prześledź ścieżkę, zanim zmienisz liczbę

Prześledź jedno nieudane żądanie zamiast rozważać cały tunel. Klient pisze do tunelu, demon VPN odszyfrowuje i trasuje, a przekaźnik przyjmuje po drugiej stronie. Każdy krok zużywa deskryptory, a ten, który zwykle się kończy, jest ostatni.

Zacznij od żądania, które możesz odtworzyć, i zmierz jego czas. Jeśli uścisk dłoni TCP się kończy, ale nie przychodzi baner aplikacji, przekaźnik przejął gniazdo i utknął w potomku albo na swojej górnej nodze. Jeśli sam uścisk nigdy się nie kończy, przyczyną jest trasowanie, zapora lub stan nasłuchu, a nie sufit deskryptorów. Zanotuj, którą z dwóch form zaobserwowałeś, bo wskazują na różne procesy.

Policz także skoki, które dublują pracę. Rozgałęziający się nasłuch przekazuje każde przyjęte gniazdo potomkowi, który trzyma własną kopię, więc rzeczywista suma jest właściwością całego drzewa, nie tylko rodzica.

Odczytaj limit, który przekaźnik odziedziczył

Jedyny limit, który ma znaczenie, należy do działającego procesu, a ustawiło go to, co ten proces uruchomiło. Wpisanie ulimit -n w powłoce opisuje powłokę. Zapytaj menedżera usług, co zastosował, a potem potwierdź na PID.

systemctl show -p MainPID -p LimitNOFILE vpn-relay.service
cat /proc/$(systemctl show -p MainPID --value vpn-relay.service)/limits

Plik limits wypisuje miękki i twardy sufit tak, jak widzi je proces. Niska wartość miękka pod hojną twardą oznacza, że demon może podnieść własny sufit, a niektóre robią to przy starcie; równe niskie wartości oznaczają, że źródłem jest plik unit.

Pliki drop-in ładują się w kolejności leksykograficznej i późniejsze wygrywają, więc systemctl cat vpn-relay.service jest autorytatywnym widokiem tego, co obowiązuje. Edycja pliku, którego menedżer nigdy nie czyta, to najczęstsza przyczyna braku efektu podniesionej liczby.

Oddziel stałą współbieżność od stanu zatrzymanego

Dwa procesy mogą uderzyć w ten sam sufit z niepowiązanych powodów, a środki zaradcze się różnią. Popyt śledzący użyteczne współbieżne sesje to kwestia pojemności. Wzrost, który trwa po zakończeniu pracy, to wyciek albo zbiór sesji, których nikt nie zamknął.

Mierz na biegu jałowym, w normalnym szczycie i ponownie kilka minut po ustaniu obciążenia. Zliczanie otwartych wpisów za pomocą ls /proc/PID/fd | wc -l wobec miękkiego limitu pokazuje lukę, a wynik o jeden lub dwa poniżej sufitu to twarde zatrzymanie, nie wolna ścieżka.

Gdy liczba nie chce spadać, patrz na stany gniazd, a nie na sumy. Deskryptory siedzące w CLOSE_WAIT oznaczają, że peer zamknął, a twoja strona nigdy tego nie zrobiła, co jest defektem cyklu życia aplikacji, który większy limit tylko odsuwa. Ogranicz też model potomków: rozgałęziający się przekaźnik bez limitu współbieżnych potomków wyczerpuje deskryptory, sloty procesów i pamięć naraz.

Sprawdź nową wartość na żywym procesie

Po edycji unit przeładuj menedżera i uruchom usługę ponownie, ponieważ samo przeładowanie nigdy nie zastępuje limitów, które działający proces już odziedziczył. Sprawdź na procesie, który naprawdę obsługuje ruch.

systemctl daemon-reload
systemctl restart vpn-relay.service
awk '/Max open files/ {print}' /proc/$(systemctl show -p MainPID --value vpn-relay.service)/limits
ss -tnp state established '( sport = :2222 )' | wc -l

Linia awk zwraca nową parę; jeśli nadal pokazuje starą, edytowany drop-in nie jest tym, który się ładuje. Liczba ss to twoja kontrola obciążenia, więc otwórz oczekiwaną liczbę sesji i patrz, jak rośnie. Liczba, która dalej rośnie po zamknięciu tych sesji, oznacza, że limit nigdy nie był całym problemem.

Jedno zastrzeżenie towarzyszy każdemu dużemu podniesieniu. Aplikacje odpytujące za pomocą select() nie mogą obserwować deskryptorów powyżej FD_SETSIZE, co wynosi 1024 w typowych kompilacjach, więc sufit podniesiony wyżej może powodować błędy, które wyglądają na niepowiązane. Dokumentacja wykonywania systemd niesie to samo ostrzeżenie dla uruchamianych przez nie usług.

Trzymaj restart z dala od dostępności tunelu

Restart przekaźnika zrzuca jego aktywne sesje, a to odrębne zdarzenie od padnięcia VPN. Uporządkuj zmianę tak, aby tunel pozostał w górze, gdy przekaźnik się przełącza, i ostrzeż każdego, czyja długa sesja to przecina.

Wycofanie to poprzedni plik unit plus jeszcze jeden restart, i ten plik zostaje na miejscu, aż nowa wartość przetrwa dzień pracy. Potem zamknij pętlę żądaniem, które pierwotnie zawiodło: jedna nowa sesja SSH przez przekaźnik, jedno przesłanie wystarczająco długie, by miało znaczenie, i liczba deskryptorów, która wraca do poziomu spoczynku.

Powiązane artykuły