Ostatnio zdaliśmy sobie sprawę z problemu z połączeniem TCP, który ogranicza się głównie do użytkowników komputerów Mac i Linux, którzy przeglądają nasze witryny.
Z perspektywy użytkownika przedstawia się jako bardzo długi czas połączenia z naszymi stronami internetowymi (> 11 sekund).
Udało nam się wyśledzić techniczną sygnaturę tego problemu, ale nie możemy zrozumieć, dlaczego tak się dzieje ani jak go naprawić.
Zasadniczo dzieje się tak, że komputer klienta wysyła pakiet SYN w celu nawiązania połączenia TCP, a serwer sieciowy go odbiera, ale nie odpowiada pakietem SYN / ACK. Po tym, jak klient wysłał wiele pakietów SYN, serwer w końcu odpowiada pakietem SYN / ACK i wszystko jest w porządku dla pozostałej części połączenia.
I, oczywiście, przyczyna problemu: jest sporadyczna i nie zdarza się cały czas (chociaż zdarza się to między 10-30% czasu)
Używamy Fedory 12 Linux jako systemu operacyjnego i Nginx jako serwera WWW.
Zrzut ekranu z analizy wireshark
Aktualizacja:
Wyłączenie skalowania okna na kliencie zatrzymało problem. Teraz potrzebuję tylko rozwiązania po stronie serwera (nie możemy zmusić wszystkich klientów do robienia tego) :)
Ostatnia aktualizacja:
Rozwiązaniem było wyłączenie skalowania okna TCP i znaczników czasu TCP na naszych serwerach, które są publicznie dostępne.
źródło
Odpowiedzi:
Mieliśmy ten sam problem. Wyłączenie znaczników czasu TCP rozwiązało problem.
Aby wprowadzić tę zmianę na stałe, wprowadź dane w polu
/etc/sysctl.conf
.Należy bardzo uważać przy wyłączaniu opcji Skalowania okna TCP. Ta opcja jest ważna dla zapewnienia maksymalnej wydajności przez Internet. Ktoś z połączeniem 10 Mb / s będzie miał transfer nieoptymalny, jeśli czas podróży w obie strony (w zasadzie taki sam jak ping) jest dłuższy niż 55 ms.
Naprawdę zauważyliśmy ten problem, gdy za tym samym NATem było wiele urządzeń. Podejrzewam, że serwer mógł być zdezorientowany widząc znaczniki czasu z urządzeń z Androidem i maszyn OSX w tym samym czasie, ponieważ umieszczają one zupełnie inne wartości w polach znaczników czasu.
źródło
W moim przypadku następujące polecenie naprawiło problem z brakującymi odpowiedziami SYN / ACK z serwera Linux:
Myślę, że jest to bardziej poprawne niż wyłączenie znaczników czasu TCP, ponieważ znaczniki czasu TCP są przydatne do wysokiej wydajności (PAWS, skalowanie okien itp.).
Dokumentacja
tcp_tw_recycle
wyraźnie stwierdza, że nie jest zalecane włączenie tej opcji, ponieważ wiele routerów NAT zachowuje znaczniki czasu, a zatem PAWS uruchamia się, ponieważ znaczniki czasu z tego samego adresu IP nie są spójne.źródło
net.ipv4.tcp_tw_recycle
jest to prawdziwy powód. Dzięki.Zastanawiam się, ale dlaczego w przypadku pakietu SYN (ramka 539; ta, która została zaakceptowana) w polach „Informacje” brakuje pól WS i TSV?
WS to Skalowanie okna TCP, a TSV to Wartość znacznika czasu . Oba znajdują się w polu tcp.options, a Wireshark nadal powinien je pokazywać, jeśli są obecne. Może podczas 8. próby stos TCP / IP klienta odmawia wysłania innego pakietu SYN i to był powód, dla którego został nagle potwierdzony?
Czy możesz podać nam wartości wewnętrzne ramki 539? Czy SYN / ACK zawsze przychodzi dla pakietu SYN, który nie ma włączonej WS?
źródło
Właśnie natrafiliśmy na dokładnie ten sam problem (naprawdę zajęło sporo czasu przypięcie go do serwera, który nie wysyła synchronizacji).
„Rozwiązaniem było wyłączenie skalowania okien tcp i znaczników czasu tcp na naszych serwerach, które są publicznie dostępne”.
źródło
Aby kontynuować to, co stwierdził Ansis, widziałem takie problemy, gdy zapora nie obsługuje skalowania Windows TCP. Co to jest zapora marki / modelu między tymi dwoma hostami?
źródło
Brak SYN / ACK może być spowodowany zbyt niskimi limitami ochrony SYNFLOOD na zaporze ogniowej. Zależy to od liczby połączeń z użytkownikiem serwera. Korzystanie ze spdy zmniejszyłoby liczbę połączeń i mogłoby pomóc w sytuacji, w której wyłączenie
net.ipv4.tcp_timestamps
nie pomaga.źródło
Jest to zachowanie nasłuchującego gniazda TCP, gdy jego zaległość jest pełna.
Ngnix pozwala ustawić argument backlog nasłuchiwać w konfiguracji: http://wiki.nginx.org/HttpCoreModule#listen
posłuchaj 80 zaległości = liczba
Spróbuj ustawić wartość num na coś większego niż domyślny, np. 1024.
Nie udzielam żadnej gwarancji, że pełna kolejka nasłuchu jest twoim problemem, ale to dobra pierwsza rzecz do sprawdzenia.
źródło
Właśnie odkryłem, że klienci Linux Linux zmieniają swój pakiet SYN po 3 próbach i usuwają opcję skalowania okna. Wydaje mi się, że programiści jądra stwierdzili, że jest to częsta przyczyna awarii połączenia w Internecie
Wyjaśnia, dlaczego tym klientom udaje się połączyć po 11 sekundach (mój krótki test TCP SYN występuje po 9 sekundach w moim krótkim teście z ustawieniami domyślnymi)
źródło
Miałem podobny problem, ale w moim przypadku błędnie obliczono sumę kontrolną TCP. Klient stał za veth i uruchomił ethtool -K veth0 rx off tx off załatwiło sprawę.
źródło