Czy zmiana wartości / proc / sys / net / ipv4 / tcp_tw_reuse jest niebezpieczna?

10

Mamy kilka systemów produkcyjnych, które zostały niedawno przekształcone w maszyny wirtualne. Istnieje nasza aplikacja, która często uzyskuje dostęp do bazy danych MySQL, i dla każdego zapytania tworzy połączenie, zapytania i rozłącza to połączenie.

To nie jest odpowiedni sposób na zapytanie (wiem), ale mamy ograniczenia, których nie możemy obejść. W każdym razie problem jest taki: gdy maszyna była hostem fizycznym, program działał dobrze. Po konwersji na maszynę wirtualną zauważyliśmy sporadyczne problemy z połączeniem z bazą danych. W pewnym momencie było ponad 24000 połączeń gniazd w TIME_WAIT (na hoście fizycznym najwięcej widziałem 17000 - nie jest dobrze, ale nie powoduje problemów).

Chciałbym, aby te połączenia były ponownie używane, abyśmy nie widzieli tego problemu z połączeniem, a więc:

Pytania:

Czy można ustawić wartość tcp_tw_reuse na 1? Jakie są oczywiste niebezpieczeństwa? Czy jest jakiś powód, dla którego nigdy nie powinienem tego robić?

Ponadto, czy jest jakiś inny sposób, aby uzyskać system (RHEL / CentOS), aby uniemożliwić tak wielu połączeniom przejście do TIME_WAIT lub sprawienie, aby były ponownie wykorzystywane?

Co wreszcie zrobi zmiana tcp_tw_recycle i czy to mi pomoże?

Z góry dzięki!

Sagar
źródło
1
Ten link dobrze wyjaśnia niebezpieczeństwo tcp_tw_recycle i tcp_tw_reuse. Nie używaj tego.

Odpowiedzi:

8

Możesz bezpiecznie skrócić czas przestoju, ale możesz napotkać problemy z nieprawidłowo zamkniętymi połączeniami w sieciach z utratą lub fluktuacją pakietów. Nie zaczynam strojenia od 1 sekundy, zaczynam od 15-30 i pracuję w dół.

Ponadto naprawdę musisz naprawić swoją aplikację.

RFC 1185 ma dobre wyjaśnienie w sekcji 3.2:

Gdy połączenie TCP jest zamknięte, opóźnienie 2 * MSL w stanie TIME-WAIT wiąże parę gniazd przez 4 minuty (patrz Rozdział 3.5 [Postel81]. Aplikacje zbudowane na TCP, które zamykają jedno połączenie i otwierają nowe (np. , połączenie przesyłania danych FTP w trybie Stream) musi za każdym razem wybierać nową parę gniazd. Opóźnienie to służy dwóm różnym celom:

 (a)  Implement the full-duplex reliable close handshake of TCP. 

      The proper time to delay the final close step is not really 
      related to the MSL; it depends instead upon the RTO for the 
      FIN segments and therefore upon the RTT of the path.* 
      Although there is no formal upper-bound on RTT, common 
      network engineering practice makes an RTT greater than 1 
      minute very unlikely.  Thus, the 4 minute delay in TIME-WAIT 
      state works satisfactorily to provide a reliable full-duplex 
      TCP close.  Note again that this is independent of MSL 
      enforcement and network speed. 

      The TIME-WAIT state could cause an indirect performance 
      problem if an application needed to repeatedly close one 
      connection and open another at a very high frequency, since 
      the number of available TCP ports on a host is less than 
      2**16.  However, high network speeds are not the major 
      contributor to this problem; the RTT is the limiting factor 
      in how quickly connections can be opened and closed. 
      Therefore, this problem will no worse at high transfer 
      speeds. 

 (b)  Allow old duplicate segements to expire. 

      Suppose that a host keeps a cache of the last timestamp 
      received from each remote host.  This can be used to reject 
      old duplicate segments from earlier incarnations of the 

* Uwaga: Można argumentować, że strona wysyłająca FIN wie, jakiego stopnia niezawodności potrzebuje, a zatem powinna być w stanie określić długość opóźnienia CZAS OCZEKIWANIA dla odbiorcy FIN. Można to osiągnąć za pomocą odpowiedniej opcji TCP w segmentach FIN.

      connection, if the timestamp clock can be guaranteed to have 
      ticked at least once since the old conennection was open. 
      This requires that the TIME-WAIT delay plus the RTT together 
      must be at least one tick of the sender's timestamp clock. 

      Note that this is a variant on the mechanism proposed by 
      Garlick, Rom, and Postel (see the appendix), which required 
      each host to maintain connection records containing the 
      highest sequence numbers on every connection.  Using 
      timestamps instead, it is only necessary to keep one quantity 
      per remote host, regardless of the number of simultaneous 
      connections to that host.
duffbeer703
źródło
Dziękuję za wyjaśnienie. Problem tkwi w bibliotece, nad którą nie mam kontroli.
Sagar
6

To nie odpowiada na twoje pytanie (i jest 18 miesięcy spóźnienia), ale sugeruje inny sposób na ponowne wykorzystanie portów przez starszą aplikację:

Przydatną alternatywą dla ustawienia tcp_tw_reuse(lub tcp_tw_recycle) w systemie jest wstawienie biblioteki współdzielonej (przy użyciu LD_PRELOAD) do aplikacji; ta biblioteka może następnie pozwolić na ponowne użycie portu. To sprawia, że ​​starsza aplikacja pozwala na ponowne użycie portu bez wymuszania tego we wszystkich aplikacjach w systemie (nie jest wymagana modyfikacja aplikacji), co ogranicza wpływ poprawek. Na przykład,

    LD_PRELOAD=/opt/local/lib/libreuse.so ./legacy_app

Ta współużytkowana biblioteka powinna przechwytywać socket()wywołanie, wywoływać prawdziwe gniazdo () i ustawiać SO_REUSEADDR i / lub SO_REUSEPORT na zwróconym gnieździe. Spójrz na http://libkeepalive.sourceforge.net, aby zobaczyć przykład, jak to zrobić (to włącza Keepalives, ale włączanie SO_REUSEPORT jest bardzo podobne). Jeśli Twoja źle zachowana starsza aplikacja korzysta z protokołu IPv6, pamiętaj o zmianie wiersza 55 libkeepalive.cz

    if((domain == PF_INET) && (type == SOCK_STREAM)) {

do

    if(((domain == PF_INET) || (domain == PF_INET6)) && (type == SOCK_STREAM)) {

Jeśli utkniesz, wyślij mi e-mail, a ja napiszę kod i wyślę go do Ciebie.

Mark Wittenberg
źródło
6

Myślę, że dobrze jest zmienić tę wartość na 1. Bardziej odpowiednim sposobem może być użycie polecenia:

[root@server]# sysctl -w net.ipv4.tcp_tw_reuse=1

Nie mam żadnych oczywistych zagrożeń, o których wiem, ale szybkie wyszukiwanie w Google daje ten link, który potwierdza, że tcp_tw_reusejest to lepsza alternatywa niż tcp_tw_recycle, ale niezależnie od tego należy z niej korzystać ostrożnie.

atx
źródło
2
Nie, to nie tak mówi. Mówi (mówiąc o tcp_tw_reuse): „Jest to na ogół bezpieczniejsza alternatywa dla tcp_tw_recycle”.
Fantius
0

Połączenie nie może być ponownie użyte, jeśli są w CZASIE OCZEKIWANIA. Jeśli nie masz utraty pakietów w sieci między aplikacją a MySQL, możesz skrócić czas oczekiwania.

Jednak najlepszym rozwiązaniem jest użycie trwałych połączeń z bazą danych i pulą połączeń.

Mircea Vutcovici
źródło
1
W rzeczywistości niekoniecznie jest to prawda. Niektóre systemy zezwalają na korzystanie z gniazd w TIME_WAIT, o to właśnie chodzi w moim pytaniu. Nie to, czy jest to możliwe, ale jakie są oczywiste i nieoczywiste niebezpieczeństwa. Dzięki!
Sagar