Ostatnio mieliśmy serwer Apache, który reagował bardzo wolno z powodu zalania SYN. Obejściem tego problemu było włączenie funkcji tcp_syncookies ( net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf
).
Wysłałem pytanie na ten temat , jeśli chcesz uzyskać więcej informacji.
Po włączeniu synchronizacji zaczęliśmy widzieć następującą wiadomość w / var / log / messages co około 60 sekund:
[84440.731929] possible SYN flooding on port 80. Sending cookies.
Vinko Vrsalovic poinformował mnie, że to oznacza, że zaległości syn są pełne, więc podniosłem tcp_max_syn_backlog do 4096. W pewnym momencie obniżyłem również tcp_synack_retries do 3 (w porównaniu z domyślną wartością 5), wydając sysctl -w net.ipv4.tcp_synack_retries=3
. Po wykonaniu tej czynności częstotliwość wydawała się spadać, a odstępy między wiadomościami wahały się od około 60 do 180 sekund.
Następnie wydałem sysctl -w net.ipv4.tcp_max_syn_backlog=65536
, ale nadal otrzymuję komunikat w dzienniku.
Przez cały ten czas obserwowałem liczbę połączeń w stanie SYN_RECV (przez uruchomienie watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l'
) i nigdy nie przekracza ona około 240, znacznie mniej niż rozmiar zaległości. Mam jednak serwer Red Hat, który unosi się wokół 512 (limit na tym serwerze to domyślnie 1024).
Czy są jakieś inne ustawienia TCP, które ograniczałyby rozmiar zaległości, czy też szczekam niewłaściwe drzewo? Czy liczba połączeń SYN_RECV powinna netstat -tuna
korelować z wielkością zaległości?
Aktualizacja
Najlepiej, jak mogę powiedzieć, że mam tutaj do czynienia z legalnymi połączeniami, na których netstat -tuna|wc -l
widnieje około 5000. Badałem to dzisiaj i znalazłem ten post od pracownika last.fm, który był raczej przydatny.
Odkryłem również, że tcp_max_syn_backlog nie działa, gdy synchronizacje są włączone (zgodnie z tym linkiem )
Więc jako następny krok ustawiam następujące w sysctl.conf:
net.ipv4.tcp_syn_retries = 3
# default=5
net.ipv4.tcp_synack_retries = 3
# default=5
net.ipv4.tcp_max_syn_backlog = 65536
# default=1024
net.core.wmem_max = 8388608
# default=124928
net.core.rmem_max = 8388608
# default=131071
net.core.somaxconn = 512
# default = 128
net.core.optmem_max = 81920
# default = 20480
Następnie skonfigurowałem test czasu odpowiedzi, uruchomiłem sysctl -p
i wyłączyłem synchronizację sysctl -w net.ipv4.tcp_syncookies=0
.
Po wykonaniu tej czynności liczba połączeń w stanie SYN_RECV nadal pozostawała na poziomie około 220–250, ale połączenia zaczęły się ponownie opóźniać. Gdy zauważyłem te opóźnienia, ponownie włączyłem syncookie i opóźnienia ustały.
Wierzę, że to, co widziałem, wciąż poprawiało się od stanu początkowego, jednak niektóre żądania były nadal opóźnione, co jest znacznie gorsze niż włączenie synchronizacji. Wygląda na to, że utknąłem z nimi włączonymi, dopóki nie będziemy mogli uzyskać więcej serwerów online, aby poradzić sobie z obciążeniem. Nawet wtedy nie jestem pewien, czy widzę prawidłowy powód, aby je ponownie wyłączyć, ponieważ są one wysyłane (najwyraźniej), gdy bufory serwera się zapełniają.
Ale zaległości synchronizacji nie wydają się być pełne tylko ~ 250 połączeń w stanie SYN_RECV! Czy to możliwe, że komunikat zalewania SYN to czerwony śledź i wypełnia go coś innego niż syn_backlog?
Jeśli ktoś ma jakieś inne opcje dostrajania, których jeszcze nie wypróbowałem, chętnie je wypróbuję, ale zaczynam się zastanawiać, czy z jakiegoś powodu ustawienie syn_backlog nie jest właściwie stosowane.