Przy dystrybucji programu zauważyliśmy w logach że czasami resty które wysyłamy od razu zwracają błąd.
Wygląda jakby był to problem z połączeniem i brakiem internetu.

Problem w tym, że komunikacja w całości odbywa się wewnątrz urządzenia.
Wcześniej nasłuchiwaliśmy na wszystkie porty(0.0.0.0), ale zmieniliśmy to później na 127.0.0.1 jednak to nie pomogło

Sytuacja czasami trwa nawet 30 sekund i dotyczy kilku różnych programów(w rust, pythonie i C++ więc to raczej nie wina konkretnych implementacji).
Po linuxowych logach systemowych można wywnioskować że może to być związane z odpinaniem/przepinaniem/ruszaniem kabla/gniazda lanu - ale nie jest to w 100% pewne

Da się przed tym jakoś systemowo zabezpieczyć?
Trochę bez sensu, że komunikacja wewnątrz urządzenia jest zależna od nieużywanych interfejsów sieciowych

#programowanie
#linux
groman43

>Trochę bez sensu, że komunikacja wewnątrz urządzenia jest zależna od nieużywanych interfejsów sieciowych


@qarmin Na 99.9% nie jest ti związane z nieużywanymi interfejsami sieciowymi. Odpal wiresharka i sprawdź co tam naprawdę się dzieje.

brain

W Linux adres 127.0.0.1 i localhost nie są tym samym. Ten pierwszy korzysta z całego stacka sieciowego, więc pakiety są kierowane na kartę sieciową i wracają z powrotem. Z kolei localhost jest w pełni ogarniany przez kernel. Jeżeli jest jakiś problem z kartą to możliwe że uda się go wyeliminować przez zastosowanie localhost.

LondoMollari

W Linux adres 127.0.0.1 i localhost nie są tym samym.


@brain Masz jakieś źródło tego, że to zachowanie globalne dla Linuxa? W kontekście specyficznych implementacji może tak być (np. setupu php + mysql, bo tam faktycznie wpisanie localhost domyślnie idzie przez lokalny unix socket) ale to decyzja ludzi od php-mysql, a nie coś globalnego.


Generalnie 127.0.0.1 i localhost nie muszą być tym samym, ale w większości przypadków będą, bo tak jest zdefiniowane w /etc/hosts - więc tak długo jak implementacja sieciowa zacznie od rozwiązywania hosta, to trafi na 127.0.0.1 (albo co tam w /etc/hosts wpiszesz, bo w sumie całe 127.0.0.0/8 jest zarezerwowane na lokalne połączenia - https://datatracker.ietf.org/doc/html/rfc5735 )


$ cat /etc/hosts | grep local

127.0.0.1   localhost

::1    ip6-localhost ip6-loopback

fe00::0 ip6-localnet


@qarmin Czy to co nasłuchuje na localhoście jest za jakimś reverse proxy (nginx?) czy słucha bezpośrednio? Bo jeśli jest za nginxem, to może Ci się wyczerpuje pula workerów nginxa, i serwer nie realizuje połączenia?


Jeśli nie wyczerpuje się pula połączeń w reverse proxy, to może Twój user/aplikacja dobijają do jakiegoś limitu socketów? Widziałem parę razy takie błędy, tutaj masz przykład: https://unix.stackexchange.com/questions/686238/why-am-i-hitting-file-number-limit-prematurely


I ktoś Ci już Wiresharka polecał, to dobra sugestia.

brain

@LondoMollari

Masz jakieś źródło tego, że to zachowanie globalne dla Linuxa?

Nie mam źródła i nie pamiętam gdzie na to trafiłem, ale autor tego artykułu wskazywał konkretne fragmenty w źródłach kernela gdzie pokazywał różne ścieżki przetwarzania w zależności czy to był adres numeryczny (bez znaczenia czy to było 127.0.0.0/8, 0.0.0.0, czy dowolny adres internetowy), czy wypisane "localhost". To było z 7-8 lat temu jak miałem problem z konfiguracją iptables, ale nie pamiętam teraz szczegółów. Wiem że była jakaś konfiguracja gdzie oryginalnie było 127.0.0.1, a ja ustawiłem localhost i u mnie nie chciało działać. Potem skopiowałem 1:1 konfiguracje jaką znalazłem (gdzie było 127.0.0.1) i zadziało. Metodą prób i błędów doszedłem że przyczyną było właśnie localhost zamiast 127.0.0.1 i zaciekawiony zacząłem grzebać w internecie i znalazłem tą informacje. I o ile dalej tak jest to takie zachowanie jest globalne, a nie wynikające z implementacji jakiegoś środowiska. Jedyne co mogło zmienić te zachowanie to przez te kilka lat - i kilka wersji jądra - mogli zmienić ten fragment w źródłach.

LondoMollari

@brain O zahardcodowaniu "localhost" nie słyszałem, ale nieraz się zaskakiwałem, więc jakbyś coś znalazł podeślij proszę. Zerknąłem teraz na szybko w źródła i nic specjalnego nie widzę: https://livegrep.com/search/linux?q=%22localhost%22&fold_case=true&regex=false&context=true


Na szybko przetestowałem czy hostsy są na 100% używane, i z tego co widzę jak najbardziej:


# ping -c 1 localhost

PING localhost (127.0.0.1) 56(84) bytes of data.

64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.234 ms


--- localhost ping statistics ---

1 packets transmitted, 1 received, 0% packet loss, time 0ms

rtt min/avg/max/mdev = 0.234/0.234/0.234/0.000 ms

# vim /etc/hosts # (tutaj zmieniłem na wpis w hostsach)

# ping -c 1 localhost

PING localhost (127.0.0.2) 56(84) bytes of data.

64 bytes from localhost (127.0.0.2): icmp_seq=1 ttl=64 time=0.238 ms


--- localhost ping statistics ---

1 packets transmitted, 1 received, 0% packet loss, time 0ms

rtt min/avg/max/mdev = 0.238/0.238/0.238/0.000 ms

qarmin

@LondoMollari W rust(actix), python(uvicorn) nasłuchujemy bezpośrednio na 127.0.0.1 i wysyłamy dane też na ten port z innych serwisów wszystko w obrębie jednego urządzenia, bo nie ma sensu nic pchać pomiędzy.

LondoMollari

@qarmin Jeśli masz dostęp na system i pozwolenie na nasłuch całej komunikacji, to spróbuj tcpdumpa odpalić z zapisem do pliku w momencie gdy problem występuje. Potem sobie wiresharkiem to będziesz mógł przeanalizować. Zapiszesz cały ruch sieciowy i będziesz widział w jaki sposób te połączenia się odbijają.


Ewentualnie jeszcze strace. Strace to podstawa kiedy nie mam pojęcia co się dzieje.

globalbus

@qarmin sprawdź limity otwartych plików. Socket to też plik

lurker_z_internetu

Przewijalem, żeby to napisać. Domyślny ulimit często jest za mały.

qarmin

@globalbus Jak sprawdzić czy to rzeczywiście jest problemem(bez modyfikacji limitu)?

Problem występuje jedynie u klientów, więc najlepiej gdyby to do logów systemowych było wypisane bez żadnych losowych modyfikacji poszczególnych parametrów u klienta, a nie jestem pewien czy tak jest

globalbus

@qarmin musisz sprawdzić jaki jest ulimit nofile i ile plików/socketow otwiera użytkownik (lsof?)

W rhel domyślny limit to jest ledwo 1024, więc łatwo przekroczyć.

LondoMollari

@qarmin ulimit -n Ci pokaże limit. lsof pokaże Ci wszystkie otwarte sockety/pliki.

qarmin

@globalbus @LondoMollari Limit pokazywany na ulimit -n to 1024


lsof | wc -l - pokazuje 31210 (co jest dość dziwne i wygląda że inni też mają podobną zagwozdkę - https://stackoverflow.com/questions/52876361/difference-between-ulimit-lsof-cat-proc-sys-fs-file-max)


Wydaje mi się że programy po prostu wysypałyby się gdyby taki błąd wystąpił, albo jakoś to ologwały - a nic takiego nie ma miejsca, więc nie wydaje mi się że to jest problemem

globalbus

@qarmin lsof twojego użytkownika (tego co odpala aplikacje), a nie całego systemu.

Błędy w programach to będą io exceptions typu cannot open file, cannot open socket itd

szczekoscisk

Możliwe że mimo komunikacji wewnętrznej używany jest interfejs ethernetowy. Spróbowałbym wymusić ruch lokalny przez interfejs "lo" (LOOPBACK) np. taką komenda:\

ip router add 127.0.0.0/24 dev lo

Zaloguj się aby komentować